简体   繁体   中英

How create new column an add column names by selected row in r

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)

That's an example code. It looks like this printed:

  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

I want to create a new column df$items that contains only the column names that are TRUE for each row in the data. Something like this:

  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

I thought of using apply function or use which for selecting indexes, but couldn't figure it out. Can anyone help me?

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       

You could use

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

Output

#   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        
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      

We can use pivot_longer to reshape to 'long' format and then do a group by paste

library(dplyr)
library(tidyr)
library(stringr)
df %>%
    pivot_longer(cols = a:c) %>%
    group_by(costumer) %>% 
    summarise(items = toString(name[value])) %>% 
    left_join(df)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM