【问题标题】:Comparing Groups in data.table Columns比较 data.table 列中的组
【发布时间】:2016-02-11 12:36:37
【问题描述】:

我有一个数据集,我需要用一个变量 (Day) 进行拆分,然后在另一个变量 (Group) 的组之间进行比较,执行每组统计数据(例如 mean)并进行测试。

这是我设计的一个示例:

require(data.table)
data = data.table(Day = rep(1:10, each = 10), 
                  Group = rep(1:2, times = 50),
                  V = rnorm(100))

data[, .(g1_mean = mean(.SD[Group == 1]$V),
         g2_mean = mean(.SD[Group == 2]$V),
         p.value = t.test(V ~ Group, .SD, alternative = "two.sided")$p.value),
     by = list(Day)]

产生:

    Day      g1_mean     g2_mean   p.value
 1:   1  0.883406048  0.67177271 0.6674138
 2:   2  0.007544956 -0.55609722 0.3948459
 3:   3  0.409248637  0.28717183 0.8753213
 4:   4 -0.540075365  0.23181458 0.1785854
 5:   5 -0.632543900 -1.09965990 0.6457325
 6:   6 -0.083221671 -0.96286343 0.2011136
 7:   7 -0.044674252 -0.27666473 0.7079499
 8:   8  0.260795244 -0.15159164 0.4663712
 9:   9 -0.134164758  0.01136245 0.7992453
10:  10  0.496144329  0.76168408 0.1821123

我希望得到这个结果的方式不那么迂回。

【问题讨论】:

  • 您可以使用dcast 获得平均值,即dcast(data, Day~Group, value.var='V', mean)

标签: r data.table grouping


【解决方案1】:

一种可能的紧凑替代方案,也可以为每个组应用更多功能:

DTnew <- dcast(DT[, pval := t.test(V ~ Group, .SD, alternative = "two.sided")$p.value, Day],
               Day + pval ~ paste0("g",Group), fun = list(mean,sd), value.var = "V")

给出:

> DTnew
    Day      pval   V_mean_g1    V_mean_g2   V_sd_g1   V_sd_g2
 1:   1 0.4763594 -0.11630634  0.178240714 0.7462975 0.4516087
 2:   2 0.5715001 -0.29689807  0.082970631 1.3614177 0.2745783
 3:   3 0.2295251 -0.48792449 -0.031328749 0.3723247 0.6703694
 4:   4 0.5565573  0.33982242  0.080169698 0.5635136 0.7560959
 5:   5 0.5498684 -0.07554433  0.308661427 0.9343230 1.0100788
 6:   6 0.4814518  0.57694034  0.885968245 0.6457926 0.6773873
 7:   7 0.8053066  0.29845913  0.116217727 0.9541060 1.2782210
 8:   8 0.3549573  0.14827289 -0.319017581 0.5328734 0.9036501
 9:   9 0.7290625 -0.21589411 -0.005785092 0.9639758 0.8859461
10:  10 0.9899833  0.84034529  0.850429982 0.6645952 1.5809149

代码分解

  • 首先,将pval 变量添加到带有DT[, pval := t.test(V ~ Group, .SD, alternative = "two.sided")$p.value, Day] 的数据集中
  • 由于DT 已就地更新,并且通过上一步的引用,可以直接将dcast 函数应用于该位置。
  • 在转换公式中,您可以指定需要在 RHS 上保持当前形式的变量以及需要在 LHS 上的列中分布的变量。
  • 使用fun 参数,您可以指定必须在value.var(此处为V)上使用哪个聚合函数。如果需要多个聚合函数,您可以在列表中指定它们(例如list(mean,sd))。这可以是任何类型的函数。因此,也可以使用自定义函数。

如果你想从列名中删除V_,你可以这样做:

names(DTnew) <- gsub("V_","",names(DTnew))

注意:我将 data.table 重命名为 DT,因为在函数之后命名数据集通常是不明智的(检查 ?data

【讨论】:

  • 这看起来像一个可爱的解决方案@Jaap,你能解释一下第一行是如何工作的吗?
  • @thomasfedb 添加了解释。 HTH
  • 感谢@Jaap,这非常有帮助,特别是现在知道:= 用于向数据表添加其他变量。
【解决方案2】:

虽然不是单行的,但您可以考虑将两个过程分开,然后合并结果。这可以防止您对组名进行硬编码。

首先,我们计算均值:

my_means <- dcast(data[,mean(V), by = .(Day, Group)],
                  Day~ paste0("Mean_Group", Group),value.var="V1")

或者以 cmets 中提到的 @Akrun 不那么复杂的方式,添加一些格式。

my_means <- dcast(Day~paste0("Mean_Group", Group), data=data,
              fun.agg=mean, value.var="V")

然后是 t 检验:

t_tests <- data[,.(p_value=t.test(V~Group)$p.value), by = Day]

然后合并:

output <- merge(my_means, t_tests)

【讨论】:

  • 我认为 OP 的 data.table 方法比这更直接
  • 我认为在当前版本中,是的。但如果有多个测试/描述性统计数据,它可能会更简洁。
  • 您如何扩展它以在保持简洁的同时找到每个组的sd
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-01
  • 2013-03-27
  • 2022-01-09
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 2014-04-25
相关资源
最近更新 更多