Home > Software engineering >  How to return column names in a column where the value matches a given string
How to return column names in a column where the value matches a given string

Time:06-02

I have a dataframe that looks like this:

df <- structure(list(Match_YN = c("N", "Y", "N", "Y", "N", "N"), Match_per_var = c("N", 
"N", "N", "Y", "", "N"), MATCHED.IN.CLINVAR = c("N", "Y", "", 
"Y", "", ""), MATCHED.IN.MetaSVM = c("", "", "", "", "", ""), 
    MATCHED.IN.LOF = c("", "Y", "", "N", "", ""), notes = c("", 
    "", "", "", "", "")), row.names = 11:16, class = "data.frame")

I wanted to check whether these three columns (MATCHED.IN.CLINVAR, MATCHED.IN.MetaSVM, MATCHED.IN.LOF) have Y. If yes, I wanted to append these names in column notes. I can do this in loops, but I was wondering if there is a shortcut to do this. This is what the results look like:

Match_YN Match_per_var MATCHED.IN.CLINVAR MATCHED.IN.MetaSVM MATCHED.IN.LOF notes
11        N             N                  N                                        
12        Y             N                  Y                                 Y    MATCHED.IN.CLINVAR,MATCHED.IN.LOF
13        N             N                                                           
14        Y             Y                  Y                                 N    MATCHED.IN.CLINVAR
15        N                                                                         
16        N             N                                                           

CodePudding user response:

Here is a tidyverse solution:

With . == "Y" we check for the condition across the 3 columns with .names argument of the across function we append new columns and using unite we combine all these new columns to one -> notes

library(dplyr)
library(tidyr)

df %>% 
  mutate(across(c(MATCHED.IN.CLINVAR, MATCHED.IN.MetaSVM, MATCHED.IN.LOF), ~case_when(. == "Y" ~ cur_column()), .names = 'new_{col}')) %>%
  unite(notes, starts_with('new'), na.rm = TRUE, sep = ' ')
 Match_YN Match_per_var MATCHED.IN.CLINVAR MATCHED.IN.MetaSVM MATCHED.IN.LOF                             notes
11        N             N                  N                                                                    
12        Y             N                  Y                                 Y MATCHED.IN.CLINVAR MATCHED.IN.LOF
13        N             N                                                                                       
14        Y             Y                  Y                                 N                MATCHED.IN.CLINVAR
15        N                                                                                                     
16        N             N                                                                                       

CodePudding user response:

the humble loop

ls <- c("MATCHED.IN.CLINVAR", "MATCHED.IN.MetaSVM", "MATCHED.IN.LOF")

for(var in ls) {
  df$notes[df[var] == "Y"] <- var
}

- output

               notes
1                   
2     MATCHED.IN.LOF
3                   
4 MATCHED.IN.CLINVAR
5                   
6    
  •  Tags:  
  • r
  • Related