将函数应用于data.table的行,并保持前两列和结果为data.table

时间:2019-02-22 10:32:35

标签: r data.table

对于另一个“适用于data.table的行”问题的道歉,但是我没有在其他任何答案中找到解决方案。

我有一个data.table,其中有200万行和5000列。我想保留前两列,并通过一些摘要折叠其余列。

示例:翻译此内容...

 keep1 keep2         c        d
1:     a     A 568.62060 599.4427
2:     b     B 815.63027 728.9226

对此...

   keep1 keep2     mean   median 
1:     a     A 584.0316 584.0316   
2:     b     B 772.2765 772.2765   

目前,我的解决方案保留了所有行,并且没有我希望的那么快。

library(data.table)
x = data.table(keep1=letters[1:5], keep2=LETTERS[1:5], c=runif(5, 1, 1000), d=runif(5, 1, 1000))

stats = function(x) list(mean(x), median(x))

x[,c("mean", "median") := get_stats(unlist(.SD)), 
    by = seq_len(nrow(x)), .SDcols = 3:ncol(x)]

我有两个问题:

  1. 是否有一种方法可以防止输出所有列,而是仅输出column1,column2和我所做的汇总(如示例中所示)?
  2. 有更快的方法吗?

编辑:

这里给速度问题一些背景是与基数R相比,一百万行〜50列表中的速度。它慢了将近3倍。我认为这是因为我要返回整个表而不是要返回的列,因此我希望对此有一个解决方案。

    library(data.table)

ids = function(n) sample(LETTERS, n, rep=T)
nums = function(n) runif(n, 1, 1000)
x = data.table(keep1=ids(1e6), keep2=ids(1e6), replicate(50, nums(1e6)))

stats = function(x) c(mean(x), median(x))

ss = Sys.time()
y = x[,c("mean", "median") := stats(unlist(.SD)), 
      by = seq_len(nrow(x)), .SDcols = 3:ncol(x)]
Sys.time() - ss # Time difference of 1.408833 mins


ss = Sys.time()
y = cbind(x[,1:2], t(apply(x[,3:ncol(x)], 1, function(x) c(mean(x), median(x)))))
Sys.time() - ss # Time difference of 40.196 secs

0 个答案:

没有答案