[英]For each row, get column names where data is equal to a certain value
我有一个 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 列的值等于“是”,我想向名为“预期结果”的数据框添加第 5 列。 例如,在第 1 行,我在第 1 列和第 3 列中有“是”参数。要填充预期结果列,我将连接并将第 1 列名称和第 2 列名称添加到结果中。
这是预期的完整结果:
c1, c3
c1, c2
c2
c1
c1, c3
c1
c3
我有以下代码行,但有些不太正确:
df$Expected_Result <- colnames(df)[apply(df,1,which(LETTERS="Unfit"))]
我们可以通过逻辑矩阵( df=='Yes'
)的行( MARGIN=1
)循环( apply
),转换为“数字”索引( which
),获取names
paste
其与包装器toString
paste
在一起,它是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'( indx[,1]
)的row
分组,我们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))
使用data.table
的选项
library(data.table)
setDT(df)[, rownum:=1:.N,]
df$Expected_result <- melt(df, "rownum")[,
toString(variable[value=="Yes"]), rownum]$V1
你可以尝试这样的事情:
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()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.