我有一个包含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"))]
答案 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
),得到names
和paste
以及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'(row
)indx[,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()
。