Kyle Weise
Kyle Weise

Reputation: 879

Consolidate flag columns into single column in R

Suppose I have a dataframe like this

testtbl <- data.frame(ID = c('1','2','3','4'),
                      A = c(1,0,1,1),
                      B = c(1,1,1,1),
                      C = c(0,0,0,1),
                      D = c(0,1,1,1))

> testtbl
  ID A B C D
1  1 1 1 0 0
2  2 0 1 0 1
3  3 1 1 0 1
4  4 1 1 1 1

Where columns A-D are flags that can either be 1 or 0. I would like to consolidate these columns into 1 column, where the new dataframe would look something like:

> testtbl
  ID flag
1  1 A,B
2  2 B,D
3  3 A,B,D
4  4 A,B,C,D

At little confused on how I would approach this and would appreciate any hints or help.

Upvotes: 2

Views: 227

Answers (3)

d.b
d.b

Reputation: 32548

Base R

do.call(rbind, lapply(split(testtbl, testtbl$ID), function(x)
    data.frame(ID = x[1],
               flag = paste(sort(names(x)[-1][x[-1] > 0]),
                            collapse = ","))))
#  ID    flag
#1  1     A,B
#2  2     B,D
#3  3   A,B,D
#4  4 A,B,C,D

Upvotes: 1

Dan Raps
Dan Raps

Reputation: 318

You can also do it without any libraries with an apply:

testtbl <- data.frame(ID = c('1','2','3','4'),
                  A = c(1,0,1,1),
                  B = c(1,1,1,1),
                  C = c(0,0,0,1),
                  D = c(0,1,1,1))
test<-data.frame(ID=testtbl$ID, flag=(apply(testtbl[,-1], 1, function(x) paste0(names(x)[which(x==1)], collapse=','))))

Upvotes: 3

www
www

Reputation: 39154

A solution from dplyr and tidyr.

library(dplyr)
library(tidyr)
testtbl2 <- testtbl %>%
  gather(Col, Val, -ID) %>%
  filter(Val == 1) %>%
  select(-Val) %>%
  group_by(ID) %>%
  summarise(flag = toString(Col))
testtbl2
# # A tibble: 4 x 2
#       ID       flag
#   <fctr>      <chr>
# 1      1       A, B
# 2      2       B, D
# 3      3    A, B, D
# 4      4 A, B, C, D

Upvotes: 3

Related Questions