Home > Software design >  Is there a way to call data from columns specified by a string that differs for different rows of a
Is there a way to call data from columns specified by a string that differs for different rows of a

Time:01-04

In this example, the variable "colnumber" indicates which column's data I want to extract.

col1 <- c("a", "b", "c")
col2 <- c("b", "a", "c")
col3 <- c("c", "b", "a")
colnumber <- c(1, 2, 3) 
df <- data.frame(col1, col2, col3, colnumber)

I tried to create a variable a_col and copy the data from the numbered column designated by "number" using paste0 to create the string and then converting it to a symbol:

df %%
mutate(a_col = !!sym(paste0("col", colnumber)))

What I am expecting is a new variable a_col that has the value "a" for all 3 rows.

Instead I get the following error msg:

Error in local_error_context(dots = dots, .index = i, mask = mask) : promise already under evaluation: recursive default argument reference or earlier problems?

CodePudding user response:

TRY THIS:

library(purrr)

df %>% mutate(a_col = map(colnumber, ~df[[paste0("col", .x)]]))

CodePudding user response:

Base R solution:

df$a_col <- vapply(
  seq_along(df$colnumber), 
  function(i){
    df[i, df$colnumber[i], drop = TRUE]
  },
  character(1)
)

CodePudding user response:

dplyr-based solution using a rowwise mutate():

library(dplyr)

df %>%
  rowwise %>%
  mutate(a_col = cur_data()[[paste0("col", colnumber)]]) %>%
  ungroup()

Or a base R solution using sapply() to index into each row:

df$a_col <- sapply(
  seq(nrow(df)), 
  \(row) df[row, paste0("col", df[row, "colnumber"])]
)

df

Result from either approach:

  col1 col2 col3 colnumber a_col
1    a    b    c         1     a
2    b    a    b         2     a
3    c    c    a         3     a

NB, if col1, col2, etc., are the 1st, 2nd, etc., columns in your dataset, you can omit the paste0("col") and just use the numeric index.

CodePudding user response:

Use a vectorized operation with row/column index

df$a_col <- df[1:3][cbind(seq_len(nrow(df)), df$colnumber)]

-output

> df
  col1 col2 col3 colnumber a_col
1    a    b    c         1     a
2    b    a    b         2     a
3    c    c    a         3     a
  •  Tags:  
  • r
  • Related