如何 return 值与给定字符串匹配的列中的列名称

How to return column names in a column where the value matches a given string

我有一个如下所示的数据框:

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")

我想检查这三列(MATCHED.IN.CLINVARMATCHED.IN.MetaSVMMATCHED.IN.LOF)是否有Y。如果是,我想将这些名称附加到 notes 列中。我可以循环执行此操作,但我想知道是否有执行此操作的快捷方式。结果如下:

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                                                           

这是一个tidyverse解决方案:

使用 . == "Y" 我们检查 3 列的条件 使用 across 函数的 .names 参数,我们追加新列 并使用 unite 我们将所有这些新列合并为一个 -> 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                                                                                       

简陋的循环

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