我知道这可以通过for循环完成,但我确定在data.table
的构造中有一个更优雅的解决方案。
我有两个数据表,并使用'iris'来说明我的问题:
library("data.table")
A <- as.data.table(iris) #primary data table
B <- A[Sepal.Width > 3, .N, by = Species] #count from A meeting condition
head(A, 3)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1: 5.1 3.5 1.4 0.2 setosa
#2: 4.9 3.0 1.4 0.2 setosa
#3: 4.7 3.2 1.3 0.2 setosa
B
# Species N
#1: setosa 42
#2: versicolor 8
#3: virginica 17
我想在B中添加一个新变量,它只是B代表的数据集的比例,即对于第一行,输出将是这样的:
B[, Proportion := N/nrow(A[Species == "setosa"])]
该索引的RHS显然需要是动态的,引用B行中第一列的值。
正是这个迭代让我望而却步(虽然我觉得它可能与数据表键有关吗?);非常感谢任何帮助!
答案 0 :(得分:4)
我会按如下方式处理:
A <- as.data.table(iris)
B <- A[Sepal.Width > 3, .N, by = .("spec" = Species)]
B[, Proportion := N/nrow(A[Species == spec]), by = spec]
给出:
> B
spec N Proportion
1: setosa 42 0.84
2: versicolor 8 0.16
3: virginica 17 0.34
解释:
Species
列重命名为spec
,可以防止R&amp; data.table 从不知道用于计算Proportion
的列。by = spec
会在spec
中使用正确的A[Species == spec]
。答案 1 :(得分:1)
一个问题很多解决方案; - )
library("data.table")
A <- as.data.table(iris) #primary data table
B <- A[, .(group.count = nrow(.SD[Sepal.Width > 3]), total.count = .N), by = Species]
[, Proportion := group.count / total.count]
# Just to validate the total counts:
A[, .N, by = Species][]
结果:
Species group.count total.count Proportion
1: setosa 42 50 0.84
2: versicolor 8 50 0.16
3: virginica 17 50 0.34
工作原理:
首先按物种分组,然后计算每个组(包含在当前组的变量.SD
=&#34;子数据&#34;中),从而将每个组的行再次过滤以仅计数相关的。然后我将结果用于第二个&#34;链接&#34; data.table查询(在第二个方括号内)来计算比例。
.()
运算符是data.table是abrev。列表构造函数list()
,因为我返回了多个列,所以需要它。
:=
运算符通过引用创建一个新列(=不复制整个数据表=非常快)。