gdemin / comprehenr

List comprehensions in R
20 stars 1 forks source link

reshape from long to wide #3

Open ggrothendieck opened 3 years ago

ggrothendieck commented 3 years ago

I am try to reshape from long to wide using this example which works in base R. Indometh comes with R.

# reduce size of problem and make it unbalanced
Indometh1 <- subset(Indometh, time < 2)[1:28, ]

# base R
##################################################################
reshape(Indometh1, dir = "wide", idvar = "Subject", timevar = "time")

This base R solution is closer to comprehensions and also works:

# Indometh1 is from above
ss <- unique(Indometh1$Subject); names(ss) <- ss
tt <- unique(Indometh1$time); names(tt) <- tt

L <- with(Indometh1, 
  Map(function(i) c(Subject = i, 
    Map(function(j) c(conc[Subject == i & time == j], NA)[1], tt)), ss) 
)
do.call("rbind", L)

This an attempt using comprehenr but it does not give same result.

# comprehenr - Indometh1, ss and tt are defined above
##################################################################
library(comprehenr)
with(Indometh1,
  to_df(for(i in ss)
    c(Subject = i, 
      to_list(for (j in tt)
        j = c(conc[Subject == i & time == j], NA)[1]
      )
    )
  )
)
gdemin commented 3 years ago

The issue here is that comprehenr ignores list names. So need to set names by yourself:

Indometh1 <- subset(Indometh, time < 2)[1:28, ]
ss <- unique(Indometh1$Subject); names(ss) <- ss
tt <- unique(Indometh1$time); names(tt) <- tt
L <- with(Indometh1, 
          to_df(for(i in ss) {
              curr = to_list(for(j in tt) c(conc[Subject == i & time == j], NA)[1])
              c(Subject = i, setNames(curr, paste0('conc', tt)))
          }) 
)
L
#Subject      conc0.25 conc0.5 conc0.75 conc1 conc1.25
#   1       1     1.50    0.94     0.78  0.48     0.37
#   2       2     2.03    1.63     0.71  0.70     0.64
#   3       3     2.72    1.49     1.16  0.80     0.80
#   4       4     1.85    1.39     1.02  0.89     0.59
#   5       5     2.05    1.04     0.81  0.39     0.30
#   6       6     2.31    1.44     1.03    NA       NA
ggrothendieck commented 3 years ago

Thanks. Maybe such an example should be included in the docs or maybe some way of handling names could be added.

gdemin commented 3 years ago

I will consider adding names handling. But it is not as easy as it seems because resulted list can have less elements than original list. So I will need to do something to keep names in sync with resulted list.