3

I have this dataframe:

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

I want to mutate a new_col and fill it with values conditional on string match of column number to column names.

Desired output:

  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

I tried with str_extract, str_detect ... but I can't do it!

TarJae
  • 72,363
  • 6
  • 19
  • 66

3 Answers3

3

Or using some 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()

returning

# 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
Martin Gal
  • 16,640
  • 5
  • 21
  • 39
2

We may use get after pasteing the 'a_' with 'number'

library(dplyr)
library(stringr)
df %>% 
    rowwise %>%
    mutate(new_col = get(str_c('a_', number))) %>%
    ungroup

-output

# 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

It may be better to use a vectorized option with row/column indexing

df$newcol <- df[-1][cbind(seq_len(nrow(df)),
        match(paste0("a_", df$number), names(df)[-1]))]
akrun
  • 874,273
  • 37
  • 540
  • 662
2

Or maybe this one:

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
Anoushiravan R
  • 21,622
  • 3
  • 18
  • 41