我有一个逻辑数据框:
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解决方案。
答案 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
我们也可以使用rowwise
和do
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"