提取满足条件的每一行的列名称

时间:2018-05-22 21:21:03

标签: r apply

d <- structure(
  list(
    Cl = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 
    SaCl = c(0, 1, 0, 0,0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0), 
    SiCl = c(0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L, 0L), 
    ClLo = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 
    SiClLo = c(0L, 0L, 0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 
    SaClLo = c(1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1), 
    SaLo = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 
    SaSiLo = c(0L, 0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 
    SiLo = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 
    LoSa = c(0L, 0L, 0L, 0L,0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), 
    Sa = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,0L, 0L, 0L, 0L, 0L, 0L, 0L)
  ), 
  row.names = c(NA, 20L),
  class = "data.frame"
)

每行只有一个1。我想提取列名,每行有1个,这样我的数据框看起来像

row.id | names
-------+-------
     1 | SaClLo
     2 | SaCl
     3 | SaClLo
     4 | SaClLo

我试图对每一行运行一个函数

apply(d, 1, function(x) colnames(x)[x == 1])

这给了我NULL

3 个答案:

答案 0 :(得分:4)

使用max.col查找1的位置,并使用此向量选择相应的列名称。

data.frame(row.id = 1:nrow(d),
           names = names(d)[max.col(d)])
#   row.id  names
#1       1 SaClLo
#2       2   SaCl
#3       3 SaClLo
#4       4 SaClLo
#...

答案 1 :(得分:1)

对于每一行,我们找到哪个列的值为1,然后为该行选择colnames的值。然后我们将其转换为data.frame

data.frame(names = apply(d, 1, function(x) colnames(d)[which(x == 1)]))

    names
1  SaClLo
2    SaCl
3  SaClLo
4  SaClLo
...

或者,您可以通过tibble::rowname_to_column()运行它,将row.id从rownames更改为列。

data.frame(names = apply(d, 1, function(x) colnames(d)[which(x == 1)])) %>%
    tibble::rownames_to_column()

   rowname  names
1        1 SaClLo
2        2   SaCl
3        3 SaClLo
4        4 SaClLo
...

答案 2 :(得分:1)

which的一个鲜为人知的特征是你的朋友:

> which(d==1, arr.ind=TRUE)
   row col
2    2   2
11  11   2
15  15   2
13  13   4
...

第二列是您需要的信息:

> arr_indices <- which(d == 1, arr.ind = TRUE)
> colnames(d)[ arr_indices[, 2] ]
 [1] "SaCl"   "SaCl"   "SaCl"   "ClLo"   "SaClLo" "SaClLo" "SaClLo" "SaClLo"
 [9] "SaClLo" "SaClLo" "SaClLo" "SaClLo" "SaClLo" "SaClLo" "SaClLo" "SaClLo"
[17] "SaClLo" "SaClLo" "SaClLo" "SaClLo"

你可以将它放入数据框或其他任何东西。我喜欢这个答案,因为它是相对容易阅读的代码。