【发布时间】:2014-09-11 22:05:08
【问题描述】:
我有一个大的data.table,其中包含数百万行和 30 列。这些列包含不同数量的分类特征。我想删除任何出现低于一定比例的特征。
这是一个例子:
dt <- data.table(id=1:18,col1=c(rep("a",5), rep("b",10), rep("c",3)), col2=c(rep("d",12),rep("e",5),"f"))
dt
id col1 col2
1: 1 a d
2: 2 a d
3: 3 a d
4: 4 a d
5: 5 a d
6: 6 b d
7: 7 b d
8: 8 b d
9: 9 b d
10: 10 b d
11: 11 b d
12: 12 b d
13: 13 b e
14: 14 b e
15: 15 b e
16: 16 c e
17: 17 c e
18: 18 c f
例如,我只想保留每列出现比例超过 0.5 的特征:
> dt[,.N,by=col1][N/sum(N)>0.5]
col1 N
1: b 10
和
> dt[,.N,by=col2][N/sum(N)>0.5]
col2 N
1: d 12
我的方法是遍历列并使用%in%
for (i in 1:2) dt[, paste0('newcol',i) :=lapply(dt[[paste0('col',i)]],
function(y) ifelse(y %in% dt[,.N,by=dt[[paste0('col',i)]]][N/sum(N)>0.5][[1]],y,"") )]
然后我创建一个包含合并值dt[, merge := paste(newcol1,newcol2), by=id] 的新列
这在 merge 列中得到了我想要的输出:
> dt
id col1 col2 newcol1 newcol2 merge
1: 1 a d d d
2: 2 a d d d
3: 3 a d d d
4: 4 a d d d
5: 5 a d d d
6: 6 b d b d b d
7: 7 b d b d b d
8: 8 b d b d b d
9: 9 b d b d b d
10: 10 b d b d b d
11: 11 b d b d b d
12: 12 b d b d b d
13: 13 b e b b
14: 14 b e b b
15: 15 b e b b
16: 16 c e
17: 17 c e
18: 18 c f
问题在于,这在大型数据集上确实慢。我怀疑我没有以“data.table-y”的方式处理这个问题。我还必须非常小心不要复制原始数据集,因为它几乎不适合我的 RAM,这就是为什么 data.table 首先如此吸引人的原因。不过我不在乎是否有任何中间步骤,只要过程更快。
> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: x86_64-apple-darwin10.8.0 (64-bit)
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.9.2
loaded via a namespace (and not attached):
[1] plyr_1.8.1 Rcpp_0.11.2 reshape2_1.4 stringr_0.6.2 tools_3.0.2
【问题讨论】:
-
我在理解您想要的内容时遇到了一些麻烦。您想要 (b and d) 或 (b and/or d) 的行吗?
-
您是要生成
newcols还是只对最后一列merge感兴趣? -
不清楚您是否对正在生成的新列或符合某些条件的 col1 和 col2 值感兴趣。
-
@Arun 实际上
newcols不需要中间列。这只是我试图突出我的思考过程 -
很好,
cols怎么样?我们可以覆盖它们吗?还是以后需要?
标签: r data.table