【问题标题】:Create new variable with reference from another data.table使用来自另一个 data.table 的引用创建新变量
【发布时间】:2016-01-06 20:30:53
【问题描述】:

我知道这可以通过 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 中第一列的值..

正是这个迭代让我难以理解(尽管我觉得它可能与数据表键有关?);非常感谢任何帮助!

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    我会这样处理:

    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 & data.table 不知道要使用哪一列来计算Proportion
    • 使用by = spec 可以确保在A[Species == spec] 中使用正确的spec

    【讨论】:

    • Jaap 这在我的(更大的)数据表上完美运行。我已将其标记为如此,但您介意用文字解释一下吗?我相信您对 B 的分配有所不同,因为您给了它一个不同的列/变量名称(“spec”v.“Species”)以在比例索引中使用,是吗?...为什么by 是必要的尽管?我在没有它的情况下进行了测试,发现结果不正确,但我似乎无法理解这是如何纠正它的..
    【解决方案2】:

    一个问题很多解决方案;-)

    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 = 当前组的“子数据”中),从而再次过滤每个组的行以仅计算相关行。然后我在第二个“链式”data.table 查询(在第二个方括号内)中使用结果来计算比例。

    .() 运算符是一个 data.table 是一个缩写。对于列表构造函数list() 并且因为我返回不止一列而需要。

    := 运算符通过引用创建一个新列(= 无需复制整个数据表 = 非常快)。

    【讨论】:

    • 一个问题很多解决方案 ;-) 完全同意!我也喜欢这个,因为它阐明了.SD 的使用,我只喜欢原始答案,因为它避免了额外的列——在这个例子中,它不那么明显,但是我正在使用的数据集已经很大了能够跟踪所有内容对我来说不是最理想的。尽管如此,我很感激你指出这个版本
    • @daRknight 您能否给我们提供两种解决方案的性能比较(让我们也从您的经验中学习:-)?
    猜你喜欢
    • 1970-01-01
    • 2020-11-19
    • 2012-12-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    相关资源
    最近更新 更多