R:加速功能的建议(删除数据框中的重复项)

标签 r dplyr

我的代码遇到了一些麻烦,欢迎任何让它运行得更快的建议。 我有一个看起来像这样的数据框:

Name <- c("a","a","a","a","a","b","b","b","b","c")

Category <- c("sun","cat","sun","sun","sea","sun","sea","cat","dog","cat")

More_info <- c("table","table","table","table","table","table","table","table","table","cat")
d <- data.frame(Name,Category,More_info)

因此,我在“名称”列中的每一行都有重复的条目(重复项的数量可能会有所不同)。对于每个条目(a,b,...),我想计算“类别”列中每个相应元素的总和,并保留出现最多的唯一类别。如果一个条目具有相同数量的类别,我想随机选取最多的类别之一。 因此在这种情况下,输出数据帧将如下所示:

Name <- c("a","b","c")

Category <- c("sun","dog","cat")

More_info <- c("table","table","table")
d <- data.frame(Name,Category,More_info)

a 保留太阳条目,因为它出现最多,b 将是狗或任何其他值,因为它们都与 b 一起出现一次,并且 c 不会改变。 我的函数如下所示:

    my_choosing_function <- function(x){
      tmp = dbSNP_hapmap[dbSNP_hapmap$refsnp_id==list_of_snps[x],]
      snp_freq <- as.data.frame(table(tmp$consequence_type_tv)) 
       best_hit <- snp_freq[order(-snp_freq$Freq),]
      best_hit$SNP<-list_of_snps[x]
      top<-best_hit[1,]
      return(top)
    }
    trst <- lapply(1:length(list_of_snps), function(x) my_choosing_function(x))
final <- do.call("rbind",trst)

我从唯一元素列表(在我们的例子中是名称)开始,对于每个元素,我都会创建一个重复条目的表,我按降序值对表进行排序并保留顶部元素。我对唯一值列表中的每个元素执行 lapply,然后对整个内容执行 rbind。

由于我的初始数据框中有 2500000 行和 1500000 个唯一元素,因此它需要很长时间才能运行。 100 行需要 4 秒,总共需要 34 小时。

我确信像 dplyr 这样的软件包可以在几分钟内完成,但找不到解决方案。有人有主意吗? 非常感谢您的帮助!

最佳答案

注意:这应该是一个很长的注释,因为我使用 data.table 而不是 dplyr

我建议使用data.table,因为它运行得更快。在如下所示的 data.table 方式中,它会随机选择一个,以防出现平局,而不总是第一个。

library(data.table)
library(dplyr)
library(microbenchmark)

d <- data.frame(
    Name = as.character(sample.int(10000, 2.5e6, replace = T)),
    Category = as.character(sample.int(10000, 2.5e6, replace = T)),
    More_info = rep('table', 2.5e6)
)

Mode <- function(x) {
    ux <- unique(x)
    fr1 <- tabulate(match(x, ux))
    if(n_distinct(fr1)==1) ux[sample(seq_along(fr1), 1)] else ux[which.max(fr1)]
}

system.time({
    d %>%
        group_by(Name) %>%
        slice(which(Category == Mode(Category))[1])
})
#    user  system elapsed
#  45.932   0.808  46.745

system.time({
    dt <- as.data.table(d)
    dt.max <- dt[, .N, by = .(Name, Category)]
    dt.max[, r := frank(-N, ties.method = 'random'), by = .(Name)]
    dt.max <- dt.max[r == 1, .(Name, Category)]

    dt[dt.max, on = .(Name, Category), mult = 'first']
})
#    user  system elapsed
#   2.424   0.004   2.426

关于R:加速功能的建议(删除数据框中的重复项),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47686604/

相关文章:

r - 使用 predictNLS 在 R 中的拟合值周围创建置信区间?

r - 使用 '-' 选择 (dplyr) 运算符

r - dplyr - 聚合不正确?

arrays - 通过对 R 中不同索引求和来矢量化(或加速)双循环

r - 对齐多个 xts 时间序列图

r - 使用 dplyr 分解不同年份的数据

r - 如何用R中的线性模型单独替换NA

r - 查找两个数据框中的共同条目

r - 要列出的分组数据框

r - 分开在第一个周期 R