-1

I am still new to R, and I run into this task to transform the df which I cannot solve.

I have a data frame, which I am trying to replace value of 1 (for each row) by its column name.

ID flag1 flag2 flag3 flag4
a1   1     0     1     1
a2   0     1     0     0
    df <- data.frame("ID"=c("a1","a2"), 
                      "flag1" = c(1,0),
                      "flag2" = c(0,1),
                      "flag3" = c(1,1),
                      "flag4" = c(1,1))

I understand that I will have to create a function and/or loop to accomplish my goal.

I am looking to transform the dataframe to the following

ID Name
a1 flag1
a1 flag3
a1 flag4
a2 flag2

Thank you for any help/hint.

Jon Spring
  • 55,165
  • 4
  • 35
  • 53

2 Answers2

1

Here's a tidyverse approach, which treats this as a reshaping task, where we want the column names to the right of ID to be pulled into a single new variable, and we just want to keep the 1's.

library(tidyverse)
df %>%
  gather(col, val, -ID) %>%
  filter(val == 1) %>%
  arrange(ID, col) %>%  # optional, just to sort
  select(-val)          # optional, just to remove col of 1's

  ID   col
1 a1 flag1
2 a1 flag3
3 a1 flag4
4 a2 flag2
5 a2 flag3
6 a2 flag4
Jon Spring
  • 55,165
  • 4
  • 35
  • 53
  • Thank you so much for your help. This is exactly what I was trying to get to. Any hint on how I can solve this with a function or loop as I am working on trying to get better at these too – Ngu Kha Aug 03 '19 at 14:25
0

Using 'melt' from 'data.table'

library(data.table)
df <- data.frame("ID"=c("a1","a2"), 
                     "flag1" = c(1,0),
                     "flag2" = c(0,1),
                     "flag3" = c(1,1),
                     "flag4" = c(1,1))

df <- as.data.table(df)
df2 <- melt(df, id="ID")[value==1][, value:=NULL]
df2

   ID variable
1: a1    flag1
2: a2    flag2
3: a1    flag3
4: a2    flag3
5: a1    flag4
6: a2    flag4
LocoGris
  • 4,432
  • 3
  • 15
  • 30