使用 data.table 计算依赖于许多列的函数
Using data.table to calculate a function which depends on many columns
有很多帖子讨论在使用 data.table 时在多个列上应用一个函数。但是我需要计算一个依赖于许多列的函数。例如:
# Create a data table with 26 columns. Variable names are var1, ..., var 26
data.mat = matrix(sample(letters, 26*26, replace=TRUE),ncol=26)
colnames(data.mat) = paste("var",1:26,sep="")
data.dt <- data.table(data.mat)
现在,假设我想计算第 5、6、7 和 8 列中“a”的数量。
我看不到如何使用 SDcols 执行此操作并最终执行以下操作:
data.dt[,numberOfAs := (var5=='a')+(var6=='a')+(var7=='a')+(var7=='a')]
这很乏味。有没有更明智的方法来做到这一点?
谢谢
我真的建议阅读 vignettes linked here. Section 2e from the Introduction to data.table vignette 解释 .SD
和 .SDcols
。
.SD
只是一个包含当前组数据的 data.table。 .SDcols
告诉列 .SD
应该有。一个有用的方法是使用 print
来查看内容。
# .SD contains cols 5:8
data.dt[, print(.SD), .SDcols=5:8]
由于这里没有by
,所以.SD
包含data.dt
的所有行,对应.SDcols
中指定的列。
一旦你理解了这一点,任务就会真正减少到你对基础 R 的了解。您可以通过多种方式完成此操作。
data.dt[, numberOfAs := rowSums(.SD == "a"), .SDcols=5:8]
我们通过比较 .SD
和 "a" 中的所有列来 return 一个逻辑矩阵。然后用rowSums
来总结。
使用Reduce
的另一种方式:
data.dt[, numberOfAs := Reduce(`+`, lapply(.SD, function(x) x == "a")), .SDcols=5:8]
有很多帖子讨论在使用 data.table 时在多个列上应用一个函数。但是我需要计算一个依赖于许多列的函数。例如:
# Create a data table with 26 columns. Variable names are var1, ..., var 26
data.mat = matrix(sample(letters, 26*26, replace=TRUE),ncol=26)
colnames(data.mat) = paste("var",1:26,sep="")
data.dt <- data.table(data.mat)
现在,假设我想计算第 5、6、7 和 8 列中“a”的数量。 我看不到如何使用 SDcols 执行此操作并最终执行以下操作:
data.dt[,numberOfAs := (var5=='a')+(var6=='a')+(var7=='a')+(var7=='a')]
这很乏味。有没有更明智的方法来做到这一点?
谢谢
我真的建议阅读 vignettes linked here. Section 2e from the Introduction to data.table vignette 解释 .SD
和 .SDcols
。
.SD
只是一个包含当前组数据的 data.table。 .SDcols
告诉列 .SD
应该有。一个有用的方法是使用 print
来查看内容。
# .SD contains cols 5:8
data.dt[, print(.SD), .SDcols=5:8]
由于这里没有by
,所以.SD
包含data.dt
的所有行,对应.SDcols
中指定的列。
一旦你理解了这一点,任务就会真正减少到你对基础 R 的了解。您可以通过多种方式完成此操作。
data.dt[, numberOfAs := rowSums(.SD == "a"), .SDcols=5:8]
我们通过比较 .SD
和 "a" 中的所有列来 return 一个逻辑矩阵。然后用rowSums
来总结。
使用Reduce
的另一种方式:
data.dt[, numberOfAs := Reduce(`+`, lapply(.SD, function(x) x == "a")), .SDcols=5:8]