Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fill / complete / expand columnwise

Tags:

r

dplyr

tidyr

I have this dataframe:

df <- structure(list(lg0 = c(FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, 
TRUE), lg2 = c(FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE
), lg4 = c(TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), ld0 = c(TRUE, 
TRUE, TRUE, FALSE, FALSE, TRUE, FALSE), ld1 = c(FALSE, FALSE, 
FALSE, TRUE, FALSE, FALSE, TRUE), ld2 = c(FALSE, FALSE, FALSE, 
FALSE, TRUE, FALSE, FALSE), ld4 = c(FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE)), class = "data.frame", row.names = c(NA, 
-7L))

    lg0   lg2   lg4   ld0   ld1   ld2   ld4
1 FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE
2 FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE
3  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
4  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE
5  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
6  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
7  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE

How can I add missing columns lg1, lg3, ld3 filled with FALSE.

I would like to 'quasi' complete / fill / expand missing COLUMNS to have this:

This should be independent on which of the columns are not present, this can change.

Desired Output:

lg0   lg1   lg2   lg3   lg4   ld0   ld1   ld2   ld3   ld4  
FALSE FALSE FALSE FALSE TRUE  TRUE  FALSE FALSE FALSE FALSE
FALSE FALSE TRUE  FALSE FALSE TRUE  FALSE FALSE FALSE FALSE
TRUE  FALSE FALSE FALSE FALSE TRUE  FALSE FALSE FALSE FALSE
TRUE  FALSE FALSE FALSE FALSE FALSE TRUE  FALSE FALSE FALSE
TRUE  FALSE FALSE FALSE FALSE FALSE FALSE TRUE  FALSE FALSE
TRUE  FALSE FALSE FALSE FALSE TRUE  FALSE FALSE FALSE FALSE
TRUE  FALSE FALSE FALSE FALSE FALSE TRUE  FALSE FALSE FALSE

So far I have tried:

library(tidyr)
library(dplyr)
library(readr)

df2 <- df1 %>% 
  pivot_longer(
    everything()
  ) %>% 
  mutate(id = parse_number(name)) 

expand(df2, id, name)
like image 929
TarJae Avatar asked Jan 24 '23 04:01

TarJae


1 Answers

In base R, we can construct a new dataset of FALSE and assign the 'df' back to it based on the matching column names

nm1 <- paste0(rep(c("lg", "ld"), each = 5), 0:4)
df2 <- as.data.frame(matrix(FALSE, nrow = nrow(df), 
        ncol = length(nm1), dimnames = list(NULL, nm1)))
df2[names(df)] <- df

-output

> df2
    lg0   lg1   lg2   lg3   lg4   ld0   ld1   ld2   ld3   ld4
1 FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
2 FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
3  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
4  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
5  TRUE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
6  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
7  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE

If we want to automatically construct the nm1

d1 <- as.numeric(sub("\\D+", "", names(df)))
nm1 <- c(t(outer(unique(sub("\\d+", "", names(df))),  
      min(d1):max(d1), FUN = paste0)))
df[setdiff(nm1, names(df))] <- FALSE
df[nm1]
like image 106
akrun Avatar answered Jan 31 '23 05:01

akrun