【问题标题】:When using `data.table`'s DT[ i , j, by], is it possible to set the column types before hand?使用 `data.table` 的 DT[ i , j, by] 时,是否可以预先设置列类型?
【发布时间】:2019-11-21 00:41:11
【问题描述】:

我正在尝试计算多个不同组的两个变量之间的相关性(例如DT[, cor.test(var1, var2), group])。每当我使用 cor.test(var1, var2, method = 'pearson') 时,这都很有效,但在我使用 cor.test(var1, var2, method = 'spearman') 时会引发错误。

library(data.table)
DT <- as.data.table(iris)

# works perfectly 
DT[,cor.test(Sepal.Length,Sepal.Width, method = 'pearson'), Species]
#       Species statistic parameter      p.value  estimate null.value
# 1:     setosa  7.680738        48 6.709843e-10 0.7425467          0
# 2:     setosa  7.680738        48 6.709843e-10 0.7425467          0
# 3: versicolor  4.283887        48 8.771860e-05 0.5259107          0
# 4: versicolor  4.283887        48 8.771860e-05 0.5259107          0
# 5:  virginica  3.561892        48 8.434625e-04 0.4572278          0
# 6:  virginica  3.561892        48 8.434625e-04 0.4572278          0
#    alternative                               method
# 1:   two.sided Pearson's product-moment correlation
# 2:   two.sided Pearson's product-moment correlation
# 3:   two.sided Pearson's product-moment correlation
# 4:   two.sided Pearson's product-moment correlation
# 5:   two.sided Pearson's product-moment correlation
# 6:   two.sided Pearson's product-moment correlation
#                       data.name  conf.int
# 1: Sepal.Length and Sepal.Width 0.5851391
# 2: Sepal.Length and Sepal.Width 0.8460314
# 3: Sepal.Length and Sepal.Width 0.2900175
# 4: Sepal.Length and Sepal.Width 0.7015599
# 5: Sepal.Length and Sepal.Width 0.2049657
#> 6: Sepal.Length and Sepal.Width 0.6525292

# error
DT[,cor.test(Sepal.Length,Sepal.Width, method = 'spearman'), Species]
# Error in `[.data.table`(DT, , cor.test(Sepal.Length, Sepal.Width, method = "spearman"), : 
# Column 2 of j's result for the first group is NULL. We rely on the column types of the first 
# result to decide the type expected for the remaining groups (and require consistency). NULL 
# columns are acceptable for later groups (and those are replaced with NA of appropriate type 
# and recycled) but not for the first. Please use a typed empty vector instead, such as 
# integer() or numeric().

问题:

我知道这个特定示例有一些变通方法,但是可以事先告诉data.table 使用DT[i,j,by = 'something'] 在任何情况下的列类型是什么?

【问题讨论】:

    标签: r syntax data.table


    【解决方案1】:

    如果您想保留所有列,而不是删除带有 NULL 的列,您可以手动设置“问题”列的类(在这种情况下,给出问题的列是“参数”)。如果该列确实包含某些组的值但不包含其他组的值,则这比删除 NULL 更可取。

    DT[, {
      res <- cor.test(Sepal.Length, Sepal.Width, method = 'spearman')
      class(res$parameter) <- 'integer'
      res
      }, Species]
    
    #      Species statistic parameter      p.value  estimate null.value alternative                          method                    data.name
    #1:     setosa  5095.097        NA 2.316710e-10 0.7553375          0   two.sided Spearman's rank correlation rho Sepal.Length and Sepal.Width
    #2: versicolor 10045.855        NA 1.183863e-04 0.5176060          0   two.sided Spearman's rank correlation rho Sepal.Length and Sepal.Width
    #3:  virginica 11942.793        NA 2.010675e-03 0.4265165          0   two.sided Spearman's rank correlation rho Sepal.Length and Sepal.Width
    

    【讨论】:

    • 你刚刚为我打开了一个全新的世界!我没有意识到你可以在 j 中有多个步骤!愚蠢的问题......它是否遵守与 R 脚本相同的规则?只是想尽可能多地从你身上吸收。谢谢你的好例子!
    • 当然 - 包含在 {..} 中的所有内容都将像任何其他 R 代码一样运行。事实上,这不仅仅是您可以在 data.table j 中执行的操作,而是可以在 any R 函数 中的anywhere 中执行此操作
    【解决方案2】:

    在我看来,错误消息实际上是不言自明的:

    j 的第一组结果的第 2 列为 NULL。 我们依赖第一个结果的列类型来决定其余组的预期类型(并且需要一致性)。 NULL 列对于后面的组是可以接受的(并且那些被替换为适当类型的 NA 并被回收),但不是第一个。请改用类型化的空向量,例如 integer() 或 numeric()。

    您可能希望使用过滤掉 NULL(但请注意每个 by 中的 NULL 位置相同:

    DT[, Filter(Negate(is.null), cor.test(Sepal.Length,Sepal.Width, method = 'spearman')), Species]
    

    输出:

          Species statistic      p.value  estimate null.value alternative                          method                    data.name
    1:     setosa  5095.097 2.316710e-10 0.7553375          0   two.sided Spearman's rank correlation rho Sepal.Length and Sepal.Width
    2: versicolor 10045.855 1.183863e-04 0.5176060          0   two.sided Spearman's rank correlation rho Sepal.Length and Sepal.Width
    3:  virginica 11942.793 2.010675e-03 0.4265165          0   two.sided Spearman's rank correlation rho Sepal.Length and Sepal.Width
    

    R: removing NULL elements from a list

    【讨论】:

    • 呃!这很好用!然而,愚蠢的问题......Filter(Negate(is.null)实际上是如何工作的? 如果这样可以更好地利用您的时间,您可以指向我一个链接。 另外,为什么Filter(Negate(is.null) 可以放在“j”位置?我有点困惑。
    • Negate 返回函数输出的逻辑反义词。 Filter 从满足条件的向量中提取元素。因此Filter(Negate(is.null))cor.test in j 的列表输出中删除NULL。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多