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