Столбцы суммы с похожими именами/префиксами в R

#r #tidyverse #data-wrangling

Вопрос:

 data <- data.frame (a_1 = 1:5, a_1.1 = 3:7, a_1.2 = 5:9, b_1 = 4:8, b_1.1= 7:11)
 

Я хочу, чтобы a_1 = a_1 a_1.1 a_1.2 b_1 = b_1 b_1.1 при сохранении столбцов a_1, a_1.1, a_1.2, b_1, b_1.1

У меня есть несколько words_number.number столбцов, поэтому я хотел бы иметь какую-то функцию или краткий фрагмент кода, но любое решение было бы очень ценно!

Ответ №1:

Мы можем использовать split данные с split.default подстрокой names и получить rowSums на list

 cbind(data, sapply(split.default(data, 
       sub("\..*", "", names(data))), rowSums))
 

Ответ №2:

Вот tidyverse решение, которое вы можете использовать:

 library(dplyr)
library(stringr)
library(purrr)

names(data) %>%
  str_extract("^[:alpha:]") %>%
  unique() %>%
  map_dfc(~ data %>% select(contains(.x)) %>% 
            reduce(~ ..1   ..2)) %>%
  set_names(~ letters[seq_along(.)]) %>%
  bind_cols(data) %>%
  relocate(c(a, b), .after = last_col())

# A tibble: 5 x 7
    a_1 a_1.1 a_1.2   b_1 b_1.1     a     b
  <int> <int> <int> <int> <int> <int> <int>
1     1     3     5     4     7     9    11
2     2     4     6     5     8    12    13
3     3     5     7     6     9    15    15
4     4     6     8     7    10    18    17
5     5     7     9     8    11    21    19
 

Ответ №3:

«Вариант» split.default использования tapply

 list2DF(
  tapply(
    as.list(data),
    gsub("\..*", "", names(data)),
    function(x) rowSums(list2DF(x))
  )
)
 

дает

   a_1 b_1
1   9  11
2  12  13
3  15  15
4  18  17
5  21  19