使用data.table返回出现在每列中的特定值的计数向量

时间:2016-08-19 23:45:00

标签: r data.table dplyr

我有一个非常大的data.table,并且一直试图返回每列中特定默认值计数的列表或向量(它们每列不同)。它是这样组织的:

set.seed(1); 
DT = as.data.table(matrix(sample(1:100, 100*100, TRUE), 100, 100))
#DT output below
param1  param2  param3  ... param100 #column names
1       1       1       ... 1        #first row = default values
.                                    #elems in remaining rows are random
.                                    # a param can be set to non default
1       666     1       ... 143      # or default values within a column
.
.
10000   1       1       ... 420

我很想知道data.table的做法是什么?我一直在筛选过去的文档,并试图避免使用内存和计算密集的循环和方法(我试图使用过滤器,lapply和分组,没有运气)。

我理想寻找的一个类似例子是计算每列中存在的非NA值的数量:

count <- colSums(!is.na(DT))
#which outputs the following:
print(count)
param1  param2  param3  ... param177
1       292     0           7

除了特定于每列的给定默认值之外,有没有办法与colSums(!is.na(DT))方法类似?因此,我不计算给定列的非NA值,而是计算出我的DT的每一列中出现的非默认值,其中每列的每个默认值都位于第一行。

2 个答案:

答案 0 :(得分:6)

嗯,我认为这就是它的意思:

set.seed(1)
DT = as.data.table(matrix(sample(1:1e5, 1e8, TRUE), ncol = 10))

# vector scan
sapply(DT, function(x) sum(x == x[1L]))
#  V1  V2  V3  V4  V5  V6  V7  V8  V9 V10 
# 124 100 111 101 113 101  94 108  79 112 

# binary search
sapply(names(DT), function(x){
    q = substitute(x == x[1L], list(x=as.symbol(x)))
    DT[eval(q), .N]
})
#  V1  V2  V3  V4  V5  V6  V7  V8  V9 V10 
# 124 100 111 101 113 101  94 108  79 112 

基准:

  • 矢量扫描需要0.22秒
  • 二进制搜索最初需要1.8秒
  • 每次即时
  • 之后二进制搜索

加速是由于data.table上的 indices ,更具体地说是自动索引。请参阅?indices并阅读the vignettes(这一个出现在第四个中)。指数也将加快数据的其他操作。要从头开始创建它们,请执行for (nm in names(DT)) setindexv(DT, nm),但当然这将花费大约1.8秒。

注意:如果您的数据是浮点数,无论您采用何种方法,都会遇到麻烦。 Floats不会像x==x[1L]这样的平等测试玩得很好。

答案 1 :(得分:1)

我们可以使用void PlayerCharacterCreation(character& Player); ^^^ reference

中的summarise_each
dplyr

以@Frank的例子,它是在

中完成的
library(dplyr)
DT %>% 
    summarise_each(funs(sum(.==first(.))))