【问题标题】:partial sums after group by in data.tabledata.table 中分组后的部分总和
【发布时间】:2015-10-05 19:15:48
【问题描述】:

假设我们得到了以下数据:

library(data.table)

letters <- sample (LETTERS[1:6], 100, replace = TRUE) 
quarks  <- sample(c("up", "down", "charme", "strange", "top", "bottom"), 
                  100, replace = TRUE)
measures<- sample(seq(1:6), 100, replace = TRUE)

df <- data.frame(letters, quarks, measures)
df <- data.table(df)
df <- df[,.(count = sum(measures)), by = list(letters, quarks)] 
df

     letters  quarks   count
 ---------------------------
 1:       A   bottom    13
 2:       A   charme     3
 3:       A     down    14
 4:       A  strange     8
 5:       A      top    11
 6:       A       up    14
 7:       B   bottom     8
 8:       B   charme    12
 9:       B     down     3

基本上,我们计算每个夸克和每个字母对应的观测值,使用库data.table 提供的[.,] 函数进行分组。

问题:我想在此附上一个新列,显示每个字母的度量总数,以便每个夸克归一化为有多少具有相同字母。特别是,这可以通过以下方式获得:

df[,.(count = sum(measures)), by = letters]

    letters count
1:       F    54
2:       E    65
3:       B    71
4:       D    36
5:       C    82
6:       A    45

通过这种方式,每个单个夸克的每个计数都可以被划分并归一化为我们与同一个字母相关联的总夸克数量。有没有办法仍然使用data.table 来实现这一点?

【问题讨论】:

  • 在生成随机示例数据集之前请使用set.seed
  • 哦,是的,当然,我的错。然而,实际数量在这里并不重要。
  • 只是让我们更容易验证我们得到了正确的结果。
  • 另外,不确定是否要更改标题,但“部分和”在数学中具有与您在此处所做的不同的特殊含义。 en.wikipedia.org/wiki/Partial_sum

标签: r group-by data.table


【解决方案1】:

您可以通过将仅按letters 分组的新摘要链接到您的第一个摘要,如下所示:

dfnew <- df[,.(count = sum(measures)), by = list(letters, quarks)
            ][, lettercount := sum(count) , by = letters]

这给出了:

> dfnew
    letters  quarks count lettercount
 1:       A strange    16          30
 2:       A    down     8          30
 3:       A     top     5          30
 4:       A  charme     1          30
 5:       B strange    13          43
 6:       B  bottom     9          43
 7:       B     top    14          43
 8:       B  charme     6          43
 9:       B    down     1          43
10:       C  charme    24          73
11:       C      up     7          73
12:       C    down    11          73
13:       C strange    18          73
14:       C     top     3          73
15:       C  bottom    10          73
16:       D    down     8          41
17:       D  charme     3          41
18:       D  bottom     7          41
19:       D      up    10          41
20:       D strange     4          41
21:       D     top     9          41
22:       E  charme    12          77
23:       E      up     8          77
24:       E     top     8          77
25:       E strange    21          77
26:       E  bottom    13          77
27:       E    down    15          77
28:       F  bottom    14          45
29:       F    down    11          45
30:       F      up    10          45
31:       F strange     8          45
32:       F  charme     2          45

如果您想要一个比率(如@Arun 在他的回答中显示的)而不是按字母求和,您可以将lettercount := sum(count) 替换为ratio := count/sum(count)


使用过的数据:

set.seed(1)
letters <- sample (LETTERS[1:6], 100, replace = TRUE) 
quarks  <- sample(c("up", "down", "charme", "strange", "top", "bottom"), 
                  100, replace = TRUE)
measures<- sample(seq(1:6), 100, replace = TRUE)

df <- data.table(letters, quarks, measures)[order(letters)]

【讨论】:

  • 我不知道链接[.,] 的可能性。确实很强大!
【解决方案2】:

另一种方法是在每个组内分组使用.SD如下:

require(data.table)
ans = df[, .(ratio=.SD[, .(tmp=sum(measures)), by=quarks]$tmp/sum(measures)), by=letters]
head(ans)
#    letters      ratio
# 1:       C 0.20588235
# 2:       C 0.13235294
# 3:       C 0.35294118
# 4:       C 0.04411765

我还是更喜欢@Jaap 给出的答案,除了我们可以直接获取比率而不是创建 lettercount 列。

【讨论】:

  • 可能在结果中也需要一个quarks col,并且可能添加一个# ... 行以说明结果有更多行。
  • 我也想过;但是,这样一来,就没有按夸克名称进行分类(而是显示为两个[.,]),是吗?
  • 我的版本是count_df &lt;- df[,{ n_let = sum(measures); temp_df = .SD[ , .(n_letq = sum(measures)), by=quarks]; c( temp_df, list( n_let = n_let, frac_letq = temp_df$n_letq/n_let ) ) }, by=letters],但我觉得它太长太丑了,不适合发帖。
猜你喜欢
  • 2020-07-10
  • 2022-01-18
  • 2013-07-18
  • 1970-01-01
  • 2021-09-30
  • 1970-01-01
  • 2014-04-01
  • 2019-11-06
  • 1970-01-01
相关资源
最近更新 更多