根据列名中的字符串改变新列并粘贴现有列中的值

Mutate a new column and paste value from existing columns conditional on string in column names

我有这个数据框:

df <- structure(list(number = 1:3, a_1 = c(1L, 4L, 7L), a_2 = c(2L, 
5L, 8L), a_3 = c(3L, 6L, 9L)), class = "data.frame", row.names = c(NA, 
-3L))

  number a_1 a_2 a_3
1      1   1   2   3
2      2   4   5   6
3      3   7   8   9

我想改变 new_col 并用以列 number 与列名称的字符串匹配为条件的值填充它。

期望的输出:

  number   a_1   a_2   a_3 new_col
   <int> <int> <int> <int>   <int>
1      1     1     2     3       1
2      2     4     5     6       5
3      3     7     8     9       9

我试过str_extractstr_detect ...但我做不到!

我们可以在 paste 将 'a_' 与 'number'

相结合后使用 get
library(dplyr)
library(stringr)
df %>% 
    rowwise %>%
    mutate(new_col = get(str_c('a_', number))) %>%
    ungroup

-输出

# A tibble: 3 x 5
  number   a_1   a_2   a_3 new_col
   <int> <int> <int> <int>   <int>
1      1     1     2     3       1
2      2     4     5     6       5
3      3     7     8     9       9

最好使用带有 row/column 索引的矢量化选项

df$newcol <- df[-1][cbind(seq_len(nrow(df)),
        match(paste0("a_", df$number), names(df)[-1]))]

或者这一个:

library(dplyr)

df %>%
  rowwise() %>%
  mutate(new_col = c_across(starts_with("a"))[grepl(number, names(df[-1]))])

# A tibble: 3 x 5
# Rowwise: 
  number   a_1   a_2   a_3 new_col
   <int> <int> <int> <int>   <int>
1      1     1     2     3       1
2      2     4     5     6       5
3      3     7     8     9       9

或者使用一些 pivot_*:

library(tidyr)
library(dplyr)

df %>% 
  pivot_longer(-number, names_pattern = "a_(\d+)") %>% 
  group_by(number) %>% 
  mutate(new_col = value[name == number]) %>% 
  pivot_wider(names_from = name, names_prefix = "a_") %>% 
  ungroup()

回归

# A tibble: 3 x 5
  number new_col   a_1   a_2   a_3
   <int>   <int> <int> <int> <int>
1      1       1     1     2     3
2      2       5     4     5     6
3      3       9     7     8     9