首页 > 解决方案 > 识别 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

标签: rdplyr

解决方案


这是一种方法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

推荐阅读