计算具有通用名称模式的列组的逐行累积平均值

zhi*_* li 8 r dplyr

语境

我想在由列名称中的模式定义的不同列集上按行计算累积平均值。

a示例数据,有两组分别以和开头的列b

a1 = c(1, 2, 3)
a2 = c(4, 5, 6)
a3 = c(7, 8, 9)
a4 = c(10, 11, 12)
b1 = c(10, 20, 30)
b2 = c(40, 50, 60)
b3 = c(70, 80, 90)
b4 = c(100, 110, 120)

df = data.frame(a1, a2, a3, a4, b1, b2, b3, b4)

> df
  a1 a2 a3 a4 b1 b2 b3  b4
1  1  4  7 10 10 40 70 100
2  2  5  8 11 20 50 80 110
3  3  6  9 12 30 60 90 120

Run Code Online (Sandbox Code Playgroud)

第一组计算在名称以 开头的列中执行a

a1_2a1是和的平均值a2

a1_3a1是、a2和的平均值a3

a1_4a1是、a2a3和的平均值a4

同样,我想对“b列”执行相同的计算:b1_2b1_3和 的计算方式与、和b1_4完全相同。a1_2a1_3a1_4

我可以a1_2使用b1_4以下代码生成。但在实际情况中,我有太多类似的变量需要生成。

library(dplyr)
df %>% 
  rowwise() %>% 
  mutate(a1_2 = mean(c(a1, a2)),
         a1_3 = mean(c(a1, a2, a3)),
         a1_4 = mean(c(a1, a2, a3, a4)),
         b1_2 = mean(c(b1, b2)),
         b1_3 = mean(c(b1, b2, b3)),
         b1_4 = mean(c(b1, b2, b3, b4))) %>% 
  ungroup()

  a1 a2 a3 a4 b1 b2 b3  b4 a1_2 a1_3 a1_4 b1_2 b1_3 b1_4
1  1  4  7 10 10 40 70 100  2.5    4  5.5   25   40   55
2  2  5  8 11 20 50 80 110  3.5    5  6.5   35   50   65
3  3  6  9 12 30 60 90 120  4.5    6  7.5   45   60   75
Run Code Online (Sandbox Code Playgroud)

问题

如何更有效地执行这些计算,而不必一一手动生成它们?这些生成的变量有一个模式,该模式就是计算多个变量的平均值。

我做了什么

我检查了一个与我相关的问题(Need to create multiple newvariables while using across() in R)。但是在这个问题中,作者生成的新变量与数据框中的其他变量没有关系,这与我遇到的问题不一样。

Qui*_*ten 3

这是dplyr一个管道中的一个选项(感谢@jav提供了很好的方法):

library(dplyr)
library(tidyr)
df %>%
  mutate(id = row_number()) %>%
  pivot_longer(cols = -id) %>%
  mutate(group = sub("^([[:alpha:]]*).*", "\\1", name),
         number = gsub(".*?([0-9]+).*", "\\1", name)) %>%
  group_by(id, group) %>%
  mutate(avg_value = cummean(value),
         col_name := paste0(group, min(number), "_", number)) %>%
  filter(number != 1) %>%
  pivot_wider(id_cols = id, names_from = col_name, values_from = avg_value) %>%
  group_by(id) %>%
  fill(everything(), .direction = "downup") %>%
  slice(1) %>%
  merge(df %>% mutate(id = row_number()), ., by = 'id') %>%
  select(-id)
#>   a1 a2 a3 a4 b1 b2 b3  b4 a1_2 a1_3 a1_4 b1_2 b1_3 b1_4
#> 1  1  4  7 10 10 40 70 100  2.5    4  5.5   25   40   55
#> 2  2  5  8 11 20 50 80 110  3.5    5  6.5   35   50   65
#> 3  3  6  9 12 30 60 90 120  4.5    6  7.5   45   60   75
Run Code Online (Sandbox Code Playgroud)

创建于 2022-09-18,使用reprex v2.0.2