对于Data.Frame的每一行,获取值为TRUE的列名

时间:2014-12-29 20:56:55

标签: r dataframe

我有一个看起来像这样的data.frame L1States_df

  BoltOn CutOn IdleOn PumpOn
1  FALSE FALSE  FALSE  FALSE
2  FALSE FALSE   TRUE  FALSE
3  FALSE FALSE   TRUE  FALSE
4  FALSE FALSE   TRUE  FALSE
5  FALSE FALSE   TRUE  FALSE
6  FALSE FALSE  FALSE   TRUE

对于L1States_df的每一行,可以有一个或没有(零)TRUE,其余的都是FALSE。 我想创建一个新的向量,其中包含每行:

  • 与TRUE相关联的列的名称(如果该行上有TRUE)
  • NA如果此行没有任何TRUE

示例所需的输出:

   State
 1 NA
 2 "IdleOn"
 3 "IdleOn"
 4 "IdleOn"
 5 "IdleOn"
 6 "PumpOn"

我试过了:

apply(L1States_df,1,function(x) names(which(x==TRUE)))

但是当该行没有NA时,这不会生成TRUE,所以我放了一个IFELSE

apply(L1States_df,1,function(x) ifelse(is.null(names(which(x==TRUE))),NA,names(which(x==TRUE))))

是否有更好/更快的方式,或者是否存在执行此类操作的预定义函数(可能是data.table)?

额外点:虽然它永远不会发生,但为了安心:如果特定线路上有多个TRUE,我怎么能获得NA?

2 个答案:

答案 0 :(得分:1)

这是一个矢量化的可能解决方案(不需要apply

indx <- which(L1States_df == TRUE, arr.ind = TRUE)
names(L1States_df)[indx[match(seq_len(nrow(L1States_df)), indx[, 1]), 2]]
## [1] NA       "IdleOn" "IdleOn" "IdleOn" "IdleOn" "PumpOn"

答案 1 :(得分:0)

另一种可能性是

m <- as.matrix(mydf)
replace(NA, row(m)[m], colnames(m)[col(m)[m]])
# [1] NA       "IdleOn" "IdleOn" "IdleOn" "IdleOn" "PumpOn"

对于奖励积分,您可以使用match在包含多个TRUE的行上生成NA

match(rowSums(mydf) > 1, TRUE)
# [1] NA NA NA NA NA NA