a<-c(TRUE,FALSE,TRUE,FALSE,TRUE,FALSE)
b<-c(TRUE,FALSE,TRUE,FALSE,FALSE,FALSE)
c<-c(TRUE,TRUE,TRUE,FALSE,TRUE,FALSE)
costumer<-c("one","two","three","four","five","six")
df<-data.frame(costumer,a,b,c)

Ese es un código de ejemplo. Se ve así impreso:

  costumer     a     b     c 
1      one  TRUE  TRUE  TRUE  
2      two FALSE FALSE  TRUE 
3    three  TRUE  TRUE  TRUE 
4     four FALSE FALSE FALSE 
5     five  TRUE FALSE  TRUE 
6      six FALSE FALSE FALSE

Quiero crear una nueva columna df $ items que contenga solo los nombres de columna que son TRUE para cada fila en los datos. Algo como esto:

  costumer     a     b     c items
1      one  TRUE  TRUE  TRUE  a,b,c
2      two FALSE FALSE  TRUE  c
3    three  TRUE  TRUE  TRUE  a,b,c
4     four FALSE FALSE FALSE 
5     five  TRUE FALSE  TRUE 
6      six FALSE FALSE FALSE

Pensé en usar la función aplicar o usar which para seleccionar índices, pero no pude resolverlo. ¿Alguien puede ayudarme?

Lo siento por muy mal inglés: /

2
Fatih Ekici 15 jun. 2020 a las 18:10

4 respuestas

La mejor respuesta

Usted podría usar

df$items <- apply(df, 1, function(x) toString(names(df)[which(x == TRUE)]))

Salida

#   custumer     a     b     c   items
# 1      one  TRUE  TRUE  TRUE a, b, c
# 2      two FALSE FALSE  TRUE       c
# 3    three  TRUE  TRUE  TRUE a, b, c
# 4     four FALSE FALSE FALSE        
# 5     five  TRUE FALSE  TRUE    a, c
# 6      six FALSE FALSE FALSE        
0
Ric S 15 jun. 2020 a las 15:24

Podemos usar pivot_longer para cambiar la forma al formato 'largo' y luego hacer un grupo por paste

library(dplyr)
library(tidyr)
library(stringr)
df %>%
    pivot_longer(cols = a:c) %>%
    group_by(costumer) %>% 
    summarise(items = toString(name[value])) %>% 
    left_join(df)
0
akrun 15 jun. 2020 a las 23:57
df$items <- apply(df, 1, function(x) paste0(names(df)[x == TRUE], collapse = ","))
df
  custumer     a     b     c items
1      one  TRUE  TRUE  TRUE a,b,c
2      two FALSE FALSE  TRUE     c
3    three  TRUE  TRUE  TRUE a,b,c
4     four FALSE FALSE FALSE      
5     five  TRUE FALSE  TRUE   a,c
6      six FALSE FALSE FALSE      
0
Chris Ruehlemann 15 jun. 2020 a las 15:25
df$items = apply(df[2:4], 1, function(x) toString(names(df[2:4])[x]))
df
#   custumer     a     b     c   items
# 1      one  TRUE  TRUE  TRUE a, b, c
# 2      two FALSE FALSE  TRUE       c
# 3    three  TRUE  TRUE  TRUE a, b, c
# 4     four FALSE FALSE FALSE        
# 5     five  TRUE FALSE  TRUE    a, c
# 6      six FALSE FALSE FALSE       
0
Gregor Thomas 15 jun. 2020 a las 15:16