获取dat等于

时间:2015-08-11 14:58:27

标签: r dataframe

我有一个包含7行和4列的数据框(df)(名为c1,c2,c3,c4):

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

如果第1列到第4列的值等于“是”,我想在名为Expected Result的数据框中添加第5列。例如,在第1行,我在第1列和第3列中有“是”参数。要填充“预期结果”列,我将连接并将Column1名称和第2列名称添加到结果中。

以下是预期的完整结果:

c1, c3    
c1, c2    
c2    
c1    
c1, c3    
c1    
c3

我有以下代码行,但有些不太正确:

df$Expected_Result <- colnames(df)[apply(df,1,which(LETTERS="Unfit"))]

3 个答案:

答案 0 :(得分:5)

使用data.table

的选项
library(data.table)
setDT(df)[, rownum:=1:.N,]
df$Expected_result <- melt(df, "rownum")[, 
                         toString(variable[value=="Yes"]), rownum]$V1

答案 1 :(得分:4)

我们可以循环(apply)通过逻辑矩阵(MARGIN=1)的行(df=='Yes'),转换为'数字'索引(which),得到namespaste以及toString的包装paste(., collapse=', ')。我们可能还需要一个if/else逻辑条件来检查一行中是否有any'是'值。如果没有,则应返回NA

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

或另一种选择是通过指定row/column来获取which arr.ind=TRUE索引。由'indx'(rowindx[,1]分组,我们paste列'df'('val')。如果缺少某些行,即没有任何“是”元素,则使用ifelse为缺失的行创建NA

 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)

数据

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

答案 2 :(得分:1)

您可以尝试以下方式:

colnames(df) <- c("c1", "c2", "c3", "c4")

test <- (apply(df,1,function(x) which(x=="Yes")))

df$cols <- lapply(test,names)

这与你最初想到的一致。

整理输出:

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

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

这会移除c()