Объединить несколько столбцов в один - PullRequest
0 голосов
/ 24 апреля 2018

У меня 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

Я хочу добавить в df столбец, содержащий объединение всех цветов, отмеченных TRUE в один:

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 операторов?

Ответы [ 4 ]

0 голосов
/ 24 апреля 2018

С 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
0 голосов
/ 24 апреля 2018

Мы можем использовать базовые 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
0 голосов
/ 24 апреля 2018

Может быть более эффективный способ сделать это без использования 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 "" 
0 голосов
/ 24 апреля 2018

например. таким образом

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            
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...