【问题标题】:Fastest way to union all联合所有的最快方法
【发布时间】:2016-03-21 14:58:07
【问题描述】:

我正在寻找将所有 100000 个列表合并到数据框中的最快方法。 union all 不是 do.call(rbind) 问题,因为我想将输出放在一列中并添加组中每个列表的最小值(为了更好地理解输出,请参见下面的代码)。

我尝试了两种不同的东西,但它们很慢,所以我正在使用 data.table 或 dplyr 或任何可以让它变得更好的东西来搜索。

重现我想要的示例:

a <- c(1:3) 
b <-  c(12:20)
relations <- list(a,b)

使用我尝试过的两种不同解决方案输出。

1 - 解决方案基本上将数据帧与列表元素上的 rbind 循环连接:

full_group <- NULL
    for(i in 1:length(relations))
  {
    full_group = rbind( full_group,
                data.frame( id = relations[[i]] , 
                group = min( relations[[i]])) )       
                print(i)        
}

2 解决方案:连接向量,然后从结果中创建一个数据框:

full_group <- NULL
groups <- NULL
id <- NULL
    for(i in 1:length(relations))
  {

id <- c(id , relations[[i]] ) 
groups <- c( groups , rep( min(relations[[i]]) , length(relations[[i]]) ) )
                print(i)        
}

 full_group = data.frame( id = id , 
                groups = groups ) 

【问题讨论】:

  • 您可以等效地分别使用unlist(relations)rep(sapply(relations, min), lengths(relations)),而不是重新分配“id”和“groups”。
  • 阅读data.table::rbindlist,相关的SO问题:stackoverflow.com/questions/15673550/…

标签: r


【解决方案1】:

根据您的第二个解决方案输出判断,您希望 stack 对列表执行的操作

stack(setNames(relations,sapply(relations,min)))
价值观 1 1 1 2 2 1 3 3 1 4 12 12 5 13 12 6 14 12 7 15 12 8 16 12 9 17 12 10 18 12 11 19 12 12 20 12

这里调用setNames 设置组的名称,这里是每个列表的最小元素。相同的代码适用于来自reshape2melt 代替stack,正如@akrun 指出的那样可能更快。

不过,Stack 和 melt 会将组分别存储为因子和字符。如果需要一个数字(可能在此处),请对其底层代码稍作修改

stack2 <- function(x,i) data.frame(values=unlist(x), ind=rep.int(i, lapply(x, length)))

stack2(relations,sapply(relations,min))

正如@alexis_laz 在 cmets 中所建议的那样。

【讨论】:

  • 天哪,您的两个解决方案都非常快。感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 2012-02-26
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2011-01-24
  • 1970-01-01
相关资源
最近更新 更多