我有一个R data.frame
(简化案例,实际上有几十个TRUE / FALSE列):
name = c("ball", "pen", "box")
red = c(TRUE, FALSE, FALSE)
green = c(TRUE, TRUE, FALSE)
blue = c(TRUE, TRUE, FALSE)
df = data.frame(name, red, green, blue)
name red green blue
1 ball TRUE TRUE TRUE
2 pen FALSE TRUE TRUE
3 box FALSE FALSE FALSE
我想将一个列附加到包含标记为TRUE
的所有颜色的串联的df中:
name red green blue color
1 ball TRUE TRUE TRUE red,green,blue
2 pen FALSE TRUE TRUE green, blue
3 box FALSE FALSE FALSE na
有没有办法在不编写繁琐的ifelse
/ paste
语句的情况下执行此操作?
答案 0 :(得分:5)
我们可以通过以下方式使用基础R toString
:
df$color <- apply(df[, -1], 1, function(x) toString(names(df[, -1])[x]));
df;
# name red green blue color
#1 ball TRUE TRUE TRUE red, green, blue
#2 pen FALSE TRUE TRUE green, blue
#3 box FALSE FALSE FALSE
答案 1 :(得分:1)
在不使用dplyr
的情况下,可能有更有效的方法,但您可以使用rowwise
和do
为每行计算:
rowwise(df) %>% do({
result = as.data.frame(.)
result$color = paste(names(result)[result == TRUE], collapse = ',')
result
})
# Source: local data frame [3 x 5]
# Groups: <by row>
#
# # A tibble: 3 x 5
# name red green blue color
# * <fct> <lgl> <lgl> <lgl> <chr>
# 1 ball TRUE TRUE TRUE red,green,blue
# 2 pen FALSE TRUE TRUE green,blue
# 3 box FALSE FALSE FALSE ""
答案 2 :(得分:1)
使用tidyverse
(此处tidyr
+ dplyr
)即可:
library(tidyverse)
df %>% gather(,,-1) %>%
filter(value) %>%
group_by(name) %>%
summarise(color=paste(key,collapse=",")) %>%
right_join(df) # left_join(df,.) to preserve your column order
# # A tibble: 3 x 5
# name color red green blue
# <fctr> <chr> <lgl> <lgl> <lgl>
# 1 ball red,green,blue TRUE TRUE TRUE
# 2 pen green,blue FALSE TRUE TRUE
# 3 box <NA> FALSE FALSE FALSE
答案 3 :(得分:0)
E.g。这样
library(tidyverse)
df %>% mutate(color = apply(df[, -1], 1, function(x) colnames(df)[-1][x]))
name red green blue color
1 ball TRUE TRUE TRUE red, green, blue
2 pen FALSE TRUE TRUE green, blue
3 box FALSE FALSE FALSE