Get column names where dat is equal to

后端 未结 3 1327
Happy的楠姐
Happy的楠姐 2021-01-12 18:12

I have a data frame (df) with 7 rows and 4 columns (named c1, c2, c3, c4):

c1  c2  c3  c4
Yes No  Yes No    
Yes Yes No  No    
No  Yes No  No    
Yes No  No         


        
相关标签:
3条回答
  • 2021-01-12 18:47

    You could try something like:

    colnames(df) <- c("c1", "c2", "c3", "c4")
    
    test <- (apply(df,1,function(x) which(x=="Yes")))
    
    df$cols <- lapply(test,names)
    

    This was along the lines of what you were initially trying I think.

    To tidy the output you could:

     df$cols <- gsub("c(", "", df$cols, fixed = TRUE)
    
     df$cols <- gsub(")", "", df$cols, fixed = TRUE)
    

    This removes the c().

    0 讨论(0)
  • 2021-01-12 18:57

    We can loop (apply) through the rows (MARGIN=1) of the logical matrix (df=='Yes'), convert to 'numeric' index (which), get the names and paste it together with a wrapper toString which is paste(., collapse=', '). We may also need a if/else logical condition to check if there are any 'Yes' values in a row. If not, it should return NA.

    df$Expected_Result <- apply(df=='Yes', 1, function(x) {
                           if(any(x)) {
                                toString(names(which(x))) 
                              }
                           else NA
                        })
    

    Or another option would to get the row/column index with which by specifying the arr.ind=TRUE. Grouped by the row of 'indx' (indx[,1]), we paste the column names of 'df' ('val'). If there are some rows missing i.e. without any 'Yes' element, then use ifelse to create NA for the missing row.

     indx <- which(df=='Yes', arr.ind=TRUE)
     val <- tapply(names(df)[indx[,2]], indx[,1], FUN=toString)
     df$Expected_Result <- ifelse(seq_len(nrow(df)) %in% names(val), val, NA)
    

    data

    df <- structure(list(c1 = c("Yes", "Yes", "No", "Yes", "Yes", "Yes", 
    "No"), c2 = c("No", "Yes", "Yes", "No", "No", "No", "No"), c3 = c("Yes", 
    "No", "No", "No", "Yes", "No", "Yes"), c4 = c("No", "No", "No", 
    "No", "No", "No", "No")), .Names = c("c1", "c2", "c3", "c4"),
    class =    "data.frame", row.names = c(NA, -7L))
    
    0 讨论(0)
  • 2021-01-12 19:02

    An option using data.table

    library(data.table)
    setDT(df)[, rownum:=1:.N,]
    df$Expected_result <- melt(df, "rownum")[, 
                             toString(variable[value=="Yes"]), rownum]$V1
    
    0 讨论(0)
提交回复
热议问题