如何结合多个总结呼叫dplyr?

发布于 2025-01-31 08:20:48 字数 729 浏览 5 评论 0原文

鉴于DF,

ww <- data.frame(
    GM = c("A", "A", "A", "A", "A", "A",
            "B", "B", "B", "B", "B", "B",
            "C", "C", "C", "C", "C", "C"),
    stanza = rep(c("Past", "Mid", "End"), 6),   
    change = c(1, 1.1, 1.4, 1, 1.3, 1.5, 1, 1.2, 1.4,
               1.1, 1.2, 1.3, .9, 1.2, 1.3, .9, 1.3, 1.5))

我想计算每个GM的过去平均值,并根据GM特定的均值来计算“变化”中的每个值。我可以使用两个dplyr调用和一个连接函数进行以下操作:

past <- ww %>%
    group_by(GM) %>%
    filter(stanza == "Past") %>%
    summarize(past.mean = mean(change))

ww <- left_join(ww, past, by = "GM")

ww %>%
    group_by(GM, stanza) %>%
    summarize(pr.change = change/past.mean)

但是必须有一种在一个dplyr调用中进行此操作的方法。

Given the df

ww <- data.frame(
    GM = c("A", "A", "A", "A", "A", "A",
            "B", "B", "B", "B", "B", "B",
            "C", "C", "C", "C", "C", "C"),
    stanza = rep(c("Past", "Mid", "End"), 6),   
    change = c(1, 1.1, 1.4, 1, 1.3, 1.5, 1, 1.2, 1.4,
               1.1, 1.2, 1.3, .9, 1.2, 1.3, .9, 1.3, 1.5))

I would like to calculate the mean for Past for each GM and the divide each value in 'change' by the GM specific mean. I can do this with two dplyr calls and a join function as follows:

past <- ww %>%
    group_by(GM) %>%
    filter(stanza == "Past") %>%
    summarize(past.mean = mean(change))

ww <- left_join(ww, past, by = "GM")

ww %>%
    group_by(GM, stanza) %>%
    summarize(pr.change = change/past.mean)

But there must be a way to do this in one dplyr call.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冷情 2025-02-07 08:20:48

data.table解决方案:

library(data.table)
setDT(ww)
ww[, pr.change := change / mean(change[stanza == "Past"]), GM]
    GM stanza change pr.change
 1:  A   Past    1.0  1.000000
 2:  A    Mid    1.1  1.100000
 3:  A    End    1.4  1.400000
 4:  A   Past    1.0  1.000000
 5:  A    Mid    1.3  1.300000
 6:  A    End    1.5  1.500000
 7:  B   Past    1.0  0.952381
 8:  B    Mid    1.2  1.142857
 9:  B    End    1.4  1.333333
10:  B   Past    1.1  1.047619
11:  B    Mid    1.2  1.142857
12:  B    End    1.3  1.238095
13:  C   Past    0.9  1.000000
14:  C    Mid    1.2  1.333333
15:  C    End    1.3  1.444444
16:  C   Past    0.9  1.000000
17:  C    Mid    1.3  1.444444
18:  C    End    1.5  1.666667

A data.table solution:

library(data.table)
setDT(ww)
ww[, pr.change := change / mean(change[stanza == "Past"]), GM]
    GM stanza change pr.change
 1:  A   Past    1.0  1.000000
 2:  A    Mid    1.1  1.100000
 3:  A    End    1.4  1.400000
 4:  A   Past    1.0  1.000000
 5:  A    Mid    1.3  1.300000
 6:  A    End    1.5  1.500000
 7:  B   Past    1.0  0.952381
 8:  B    Mid    1.2  1.142857
 9:  B    End    1.4  1.333333
10:  B   Past    1.1  1.047619
11:  B    Mid    1.2  1.142857
12:  B    End    1.3  1.238095
13:  C   Past    0.9  1.000000
14:  C    Mid    1.2  1.333333
15:  C    End    1.3  1.444444
16:  C   Past    0.9  1.000000
17:  C    Mid    1.3  1.444444
18:  C    End    1.5  1.666667
白衬杉格子梦 2025-02-07 08:20:48

无需加入,您可以直接在一个管道中计算它:

ww %>% 
  mutate(pr.change = change / mean(change[stanza == "Past"]), .by = GM) %>%

输出

   GM    stanza change pr.change
   <chr> <chr>   <dbl>     <dbl>
 1 A     Past      1       1    
 2 A     Mid       1.1     1.1  
 3 A     End       1.4     1.4  
 4 A     Past      1       1    
 5 A     Mid       1.3     1.3  
 6 A     End       1.5     1.5  
 7 B     Past      1       0.952
 8 B     Mid       1.2     1.14 
 9 B     End       1.4     1.33 
10 B     Past      1.1     1.05 
11 B     Mid       1.2     1.14 
12 B     End       1.3     1.24 
13 C     Past      0.9     1    
14 C     Mid       1.2     1.33 
15 C     End       1.3     1.44 
16 C     Past      0.9     1    
17 C     Mid       1.3     1.44 
18 C     End       1.5     1.67 

No need to join, you can compute this directly in one pipe chain:

ww %>% 
  mutate(pr.change = change / mean(change[stanza == "Past"]), .by = GM) %>%

Output

   GM    stanza change pr.change
   <chr> <chr>   <dbl>     <dbl>
 1 A     Past      1       1    
 2 A     Mid       1.1     1.1  
 3 A     End       1.4     1.4  
 4 A     Past      1       1    
 5 A     Mid       1.3     1.3  
 6 A     End       1.5     1.5  
 7 B     Past      1       0.952
 8 B     Mid       1.2     1.14 
 9 B     End       1.4     1.33 
10 B     Past      1.1     1.05 
11 B     Mid       1.2     1.14 
12 B     End       1.3     1.24 
13 C     Past      0.9     1    
14 C     Mid       1.2     1.33 
15 C     End       1.3     1.44 
16 C     Past      0.9     1    
17 C     Mid       1.3     1.44 
18 C     End       1.5     1.67 
变身佩奇 2025-02-07 08:20:48

continue

Using base R

transform(ww, pr.change = change/ave(replace(change,
    stanza != 'Past', NA), GM, FUN = function(x) mean(x, na.rm = TRUE)))

-output

 GM stanza change pr.change
1   A   Past    1.0  1.000000
2   A    Mid    1.1  1.100000
3   A    End    1.4  1.400000
4   A   Past    1.0  1.000000
5   A    Mid    1.3  1.300000
6   A    End    1.5  1.500000
7   B   Past    1.0  0.952381
8   B    Mid    1.2  1.142857
9   B    End    1.4  1.333333
10  B   Past    1.1  1.047619
11  B    Mid    1.2  1.142857
12  B    End    1.3  1.238095
13  C   Past    0.9  1.000000
14  C    Mid    1.2  1.333333
15  C    End    1.3  1.444444
16  C   Past    0.9  1.000000
17  C    Mid    1.3  1.444444
18  C    End    1.5  1.666667
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文