Search code examples
rreshape2data-transform

reshape from long to wide of non-categorical values


I need to reshape date from long to wide that has non-categorical values and not the same number of values.

An example of a dataframe:

df_long <- as.data.frame(cbind(c("id A",  "b",    "b",    "d",    "d","id B", "kh",   "kk",   "ip", "id C", "99", "id D", "id E"),c(1,1,1,1,1, 2,2,2,2,3,3,1,1)))

I need this:

df_wide <- as.data.frame(rbind(c("id A", "b", "b", "d", "d"), c("id B", "kh", "kk", "ip", ""), c("id C", "99", "", "", ""), c("id D", "", "", "", ""), c("id E", "", "", "", "")))

I don't know how to reshape this since values are not categorical and not every id has the same number of values.

So I was wondering about reshaping both from long to wide and wide to long of such data.

Thank you for your help!


Solution

  • You could do:

    a = aggregate(V1~V2,transform(df_long,V2 = cumsum(grepl("id",V1))),paste,collapse=',')[,2]
    read.csv(text=a,header = FALSE,fill = TRUE)
        V1 V2 V3 V4 V5
    1 id A  b  b  d  d
    2 id B kh kk ip   
    3 id C 99         
    4 id D            
    5 id E   
    

    since you need to transform it back, then you should do:

     f<-read.csv(text = with(df_long,tapply(V1,cumsum(grepl("id",V1)),paste0,collapse=",")), 
                  header = FALSE, fill = TRUE,stringsAsFactors = F,na.strings = "")
    
    
     print(f,na = "")
        V1 V2 V3 V4 V5
    1 id A  b  b  d  d
    2 id B kh kk ip   
    3 id C 99         
    4 id D            
    5 id E
    

    Now to transform it back to your long_data, you could do:

    with(g <- transform(stack(f),ind = c(row(f))),na.omit(g[order(ind),]))
       values ind
    1    id A   1
    6       b   1
    11      b   1
    16      d   1
    21      d   1
    2    id B   2
    7      kh   2
    12     kk   2
    17     ip   2
    3    id C   3
    8      99   3
    4    id D   4
    5    id E   5