Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert a column into multi column by groups

Tags:

r

I have a data frame(df):

group col
a     12
a     15
a     13
b     21
b     23

Desired output is also a data frame(df1):

col1  col2
12    21
15    23
13    0

Namley, I want to partition "col" of "df" by "group" into multi columns as "col1" and "col2".

When the length of each column is not equal to each other, "0" must be added end of each column untill the length of each column reaches to the maximum column length.

like image 612
oercim Avatar asked May 18 '26 11:05

oercim


1 Answers

We could either use base R functions split or unstack to split the 'col' by 'group' into a list, then pad NA to list elements that are less than the maximum length of the list element. Change the column names, replace 'NA' by 0.

  lst <- unstack(df1, col~group)
  d1 <- as.data.frame(sapply(lst, `length<-`, max(sapply(lst, length))))
  d1[is.na(d1)] <- 0
  colnames(d1) <- paste0('col', 1:ncol(d1))
  d1
 #  col1 col2
 #1   12   21
 #2   15   23
 #3   13    0

Or use stri_list2matrix from stringi

library(stringi)
d1 <- as.data.frame(stri_list2matrix(unstack(df1, col~group),
            fill=0), stringsAsFactors=FALSE)
d1[] <- lapply(d1, as.numeric)

Or using data.table/splitstackshape

library(splitstackshape)
setnames(dcast(getanID(df1, 'group'), .id~group, value.var='col',
             fill=0L)[, .id:= NULL], paste0('col', 1:2))[]
#    col1 col2
#1:   12   21
#2:   15   23
#3:   13    0
like image 121
akrun Avatar answered May 21 '26 01:05

akrun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!