对几组具有特定名称模式的列进行Rowsum

zy1mlcev  于 2023-04-27  发布在  其他
关注(0)|答案(2)|浏览(108)

我有一个 Dataframe 如下:

set.seed(123)
df <- data.frame(ID = 1:5, matrix(round(rnorm(45), 1), 5, dimnames = list(NULL, paste0(rep(c('A', 'B', 'C'), 2:4), sequence(2:4)))))

#   ID   A1   A2   B1   B2   B3   C1   C2   C3   C4
# 1  1 -0.6  1.7  1.2  1.8 -1.1 -1.7  0.4  0.7 -0.7
# 2  2 -0.2  0.5  0.4  0.5 -0.2  0.8 -0.3  0.6 -0.2
# 3  3  1.6 -1.3  0.4 -2.0 -1.0  0.2  0.9 -0.1 -1.3
# 4  4  0.1 -0.7  0.1  0.7 -0.7 -1.1  0.9 -0.3  2.2
# 5  5  0.1 -0.4 -0.6 -0.5 -0.6  1.3  0.8 -0.4  1.2

我需要对几组具有特定名称模式的列进行行求和。在本例中,我想创建A_sumB_sumC_sum,它们分别通过对以'A''B''C'开头的列求和来计算。

library(dplyr)

df %>%
  mutate(A_sum = rowSums(pick(starts_with('A'))),
         B_sum = rowSums(pick(starts_with('B'))),
         C_sum = rowSums(pick(starts_with('C'))))

#   ID   A1   A2   B1   B2   B3   C1   C2   C3   C4 A_sum B_sum C_sum
# 1  1 -0.6  1.7  1.2  1.8 -1.1 -1.7  0.4  0.7 -0.7   1.1   1.9  -1.3
# 2  2 -0.2  0.5  0.4  0.5 -0.2  0.8 -0.3  0.6 -0.2   0.3   0.7   0.9
# 3  3  1.6 -1.3  0.4 -2.0 -1.0  0.2  0.9 -0.1 -1.3   0.3  -2.6  -0.3
# 4  4  0.1 -0.7  0.1  0.7 -0.7 -1.1  0.9 -0.3  2.2  -0.6   0.1   1.7
# 5  5  0.1 -0.4 -0.6 -0.5 -0.6  1.3  0.8 -0.4  1.2  -0.3  -1.7   2.9

上面的代码运行得很好,但是如果我有更多的列而不是'A''B''C',它会重复相同的表达式很多次。

prefix <- c('A', 'B', 'C')

我怎样才能用紧凑的语法得到预期的输出呢?

编辑

一般来说,我希望prefix是灵活的,这样如果我设置prefix <- c('A', 'C'),那么B1B3就不需要求和。

t8e9dugd

t8e9dugd1#

正如您所说,您已经记录了需要求和的列名前缀:

prefix <- c('A', 'B', 'C')

然后你可以使用map()reduce()purrr来遍历它们:

  1. map()
library(dplyr)
library(purrr)

df %>%
  mutate(map_dfc(set_names(prefix, paste0, '_sum'),
                 ~ rowSums(pick(starts_with(.x)))))
  1. reduce()
df %>%
  reduce(.init = ., .x = prefix,
         .f = ~ mutate(.x, '{.y}_sum' := rowSums(pick(starts_with(.y)))))
输出
#   ID   A1   A2   B1   B2   B3   C1   C2   C3   C4 A_sum B_sum C_sum
# 1  1 -0.6  1.7  1.2  1.8 -1.1 -1.7  0.4  0.7 -0.7   1.1   1.9  -1.3
# 2  2 -0.2  0.5  0.4  0.5 -0.2  0.8 -0.3  0.6 -0.2   0.3   0.7   0.9
# 3  3  1.6 -1.3  0.4 -2.0 -1.0  0.2  0.9 -0.1 -1.3   0.3  -2.6  -0.3
# 4  4  0.1 -0.7  0.1  0.7 -0.7 -1.1  0.9 -0.3  2.2  -0.6   0.1   1.7
# 5  5  0.1 -0.4 -0.6 -0.5 -0.6  1.3  0.8 -0.4  1.2  -0.3  -1.7   2.9
kqlmhetl

kqlmhetl2#

您可以尝试split.default,然后rowSums

df %>%
  cbind(
    list2DF(
      lapply(
        split.default(
          .,
          gsub("\\d+", "_sum", names(.))
        ), rowSums
      )
    )
  )

它给出了

A1   A2   B1   B2   B3   C1   C2   C3   C4 A_sum B_sum C_sum
1 -0.6  1.7  1.2  1.8 -1.1 -1.7  0.4  0.7 -0.7   1.1   1.9  -1.3
2 -0.2  0.5  0.4  0.5 -0.2  0.8 -0.3  0.6 -0.2   0.3   0.7   0.9
3  1.6 -1.3  0.4 -2.0 -1.0  0.2  0.9 -0.1 -1.3   0.3  -2.6  -0.3
4  0.1 -0.7  0.1  0.7 -0.7 -1.1  0.9 -0.3  2.2  -0.6   0.1   1.7
5  0.1 -0.4 -0.6 -0.5 -0.6  1.3  0.8 -0.4  1.2  -0.3  -1.7   2.9

相关问题