在R的dplyr中,创建一个列,指定其他列中的哪些列为TRUE

时间:2018-04-04 06:16:25

标签: r dplyr aggregate

我有一个逻辑数据框:

df = data_frame(x = c(TRUE, TRUE, FALSE, TRUE), y = c(FALSE, FALSE, FALSE, TRUE), z = c(TRUE, TRUE, FALSE, FALSE))

df
  # A tibble: 4 x 3
    x     y     z
  <lgl> <lgl> <lgl>
1  TRUE FALSE  TRUE
2  TRUE FALSE  TRUE
3 FALSE FALSE FALSE
4  TRUE  TRUE FALSE

我想创建第四列,指示可能使用逗号,每行中3列中的哪一列的值为TRUE,即对于第1行,值为(1,3)。

我可以使用循环来完成它,但需要使用大型数据集,因此更喜欢矢量化dplyr解决方案。

1 个答案:

答案 0 :(得分:1)

如果我们需要列名,那么gather进入&#39; long&#39;格式,然后paste与TRUE值对应的列名称,并在&#39; df&#39;

中创建新列
library(tidyverse)
df %>%
  rownames_to_column('rn') %>%
  gather(key, val, -rn) %>% 
  group_by(rn) %>%
  summarise(val = toString(key[val])) %>% 
  pull(val) %>%
  mutate(df, val = .)

如果我们只需要列索引,请在&#39; val&#39;上使用which。在&#39; long&#39;中生成的列格式

df %>% 
  rownames_to_column('rn') %>%
  gather(key, val, -rn) %>% 
  group_by(rn) %>% 
  summarise(val = toString(which(val))) %>%
  pull(val) %>% 
  mutate(df, val = .)
# A tibble: 4 x 4
#  x     y     z     val  
#  <lgl> <lgl> <lgl> <chr>
#1 T     F     T     1, 3 
#2 T     F     T     1, 3 
#3 F     F     F     ""   
#4 T     T     F     1, 2 

我们也可以使用rowwisedo

执行此操作
df %>%
   rowwise() %>%
   do(data.frame(., val = toString(which(unlist(.)))))

或者我们可以使用base R和一些正则表达式

来执行此操作
df$val <- gsub("0,*|,0$", "", do.call(paste, c(col(df) * df, sep=",")))
df$val
#[1] "1,3" "1,3" ""    "1,2"