Home > Software engineering >  select values based on column index
select values based on column index

Time:12-14

I am looking to add a column to my tibble that is selected from my data frame based on the column index.

library(dplyr)

question <- c("q1","q2","q3","q4")  
a <- c("no","no","yes","no")  
b <- c("yes","yes", "no","no")  
c <- c("no","no","no","yes")  

df <- tibble(question,a,b,c)

|question |a  |b  |c  |
|-------- |---|---|---|
|q1       |no |yes|no |
|q2       |no |yes|no |
|q3       |yes|no |no |
|q4       |no |no |yes|

Here is a vector of the column numbers that hold the answers:

index <- c(3,3,2,4)

My current code has been an infinite number of iterations of this:

df <- df %>%
  rowwise() %>%
  mutate(answer = select(df,index))

and I'm hoping to result in this

|question |a  |b  |c  |answer|
|-------- |---|---|---|------|
|q1       |no |yes|no |yes   |
|q2       |no |yes|no |yes   |
|q3       |yes|no |no |yes   |
|q4       |no |no |yes|yes   |

Thank you for your help!

CodePudding user response:

You can use diag, i.e.

library(dplyr)

df %>% 
 mutate(answer = diag(as.matrix(df[index])))

# A tibble: 4 × 5
  question a     b     c     answer
  <chr>    <chr> <chr> <chr> <chr> 
1 q1       no    yes   no    yes   
2 q2       no    yes   no    yes   
3 q3       yes   no    no    yes   
4 q4       no    no    yes   yes

CodePudding user response:

You can extract values from a matrix using specific row and column indices like this: mat[cbind(x,y)]

df |>
    mutate(answer = as.matrix(df)[cbind(1:nrow(df),index)])

##>   # A tibble: 4 × 5
##>   question a     b     c     answer
##>   <chr>    <chr> <chr> <chr> <chr> 
##> 1 q1       no    yes   no    yes   
##> 2 q2       no    yes   no    yes   
##> 3 q3       yes   no    no    yes   
##> 4 q4       no    no    yes   yes   

CodePudding user response:

With [ mapply:

df %>% 
  mutate(answer = unlist(mapply(\(x, y) df[x, y], seq_along(df), index)))

# A tibble: 4 × 5
  question a     b     c     answer
  <chr>    <chr> <chr> <chr> <chr> 
1 q1       no    yes   no    yes   
2 q2       no    yes   no    yes   
3 q3       yes   no    no    yes   
4 q4       no    no    yes   yes 

Taken from here, another possibility is

df %>% 
  mutate(answer = as.matrix(df)[(index - 1) * nrow(df)   seq_along(index)])
  • Related