识别R数据框中最后一次出现的值的列名
我有一个如下所示的数据集,其中包含 1 和 0 列。我想添加最后一列,用于标识每行最后出现 0 的列名。
have = data.frame(a = c(1,0,1,1,0,0,1,1,1,0),
b = c(1,0,1,1,1,0,1,1,0,0),
c = c(0,0,0,1,0,1,1,1,1,0),
d = c(1,0,1,1,0,0,0,1,0,1),
e = c(1,1,1,1,1,1,1,1,1,1))
> have
a b c d e
1 1 1 0 1 1
2 0 0 0 0 1
3 1 1 0 1 1
4 1 1 1 1 1
5 0 1 0 0 1
6 0 0 1 0 1
7 1 1 1 0 1
8 1 1 1 1 1
9 1 0 1 0 1
10 0 0 0 1 1
我希望输出看起来像这样,其中最后一列指定最后出现的 0 的列名,如果不存在则返回 NA。
> want
a b c d e last_0
1 1 1 0 1 1 c
2 0 0 0 0 1 d
3 1 1 0 1 1 c
4 1 1 1 1 1 <NA>
5 0 1 0 0 1 d
6 0 0 1 0 1 d
7 1 1 1 0 1 d
8 1 1 1 1 1 <NA>
9 1 0 1 0 1 d
10 0 0 0 1 1 c
我试过使用 max.col 但如果零不存在,它会返回最后一个列名。还有其他解决方案吗?dplyr 解决方案是首选。
> have$last_0 = names(have)[max.col(have == 0, ties.method = "last")]
> have
a b c d e last_0
1 1 1 0 1 1 c
2 0 0 0 0 1 d
3 1 1 0 1 1 c
4 1 1 1 1 1 e
5 0 1 0 0 1 d
6 0 0 1 0 1 d
7 1 1 1 0 1 d
8 1 1 1 1 1 e
9 1 0 1 0 1 d
10 0 0 0 1 1 c
回答
这是一种方法purrr::pmap:
library(dplyr);library(purrr)
have %>%
mutate(want = pmap_chr(cur_data(),
~ tail(c(NA,names(which(c(...)==0))),1)))
a b c d e want
1 1 1 0 1 1 c
2 0 0 0 0 1 d
3 1 1 0 1 1 c
4 1 1 1 1 1 <NA>
5 0 1 0 0 1 d
6 0 0 1 0 1 d
7 1 1 1 0 1 d
8 1 1 1 1 1 <NA>
9 1 0 1 0 1 d
10 0 0 0 1 1 c
purrr:pmap是一个非常有用的函数,因为它可以按行对数据进行处理,并且它有多种风格,因此您可以控制返回的内容。您可以使用 引用整行数据c(...)。
如果您只想将该过程应用于列的子集,您可以使用dplyr::select:
have %>%
mutate(want = pmap_chr(cur_data() %>% select(a,b,c),
~ tail(c(NA,names(which(c(...)==0))),1)))
a b c d e want
1 1 1 0 1 1 c
2 0 0 0 0 1 c
3 1 1 0 1 1 c
4 1 1 1 1 1 <NA>
5 0 1 0 0 1 c
6 0 0 1 0 1 b
7 1 1 1 0 1 <NA>
8 1 1 1 1 1 <NA>
9 1 0 1 0 1 b
10 0 0 0 1 1 c
回答
我们可以使用max.col然后替换那些没有任何 0 的元素到NA
have$last_0 <- names(have)[(NA^!rowSums(have == 0)) * max.col(have == 0, 'last')]
-输出
have
a b c d e last_0
1 1 1 0 1 1 c
2 0 0 0 0 1 d
3 1 1 0 1 1 c
4 1 1 1 1 1 <NA>
5 0 1 0 0 1 d
6 0 0 1 0 1 d
7 1 1 1 0 1 d
8 1 1 1 1 1 <NA>
9 1 0 1 0 1 d
10 0 0 0 1 1 c
- Brilliant strategy! +1