1

I have a 3 ways frequency table, I want to combine them into a list, normally I write listOfTable <- list(table[,,1],table[,,2],table[,,3],table[,,4],table[,,5]), sometimes my table is really long, there is any way I can apply lapply to combine as a list without doing manually.

df <- data.frame(ID = c(rep(c("A","B","C"),5)),
             N = c(rep(c("1","2","3"),5)),
             M = c(rep(1,3),rep(2,3),rep(3,3),rep(4,3),rep(5,3)))
applyAlist <- table(df$ID,df$N,df$M)
listOfTable <- list(applyAlist[,,1],applyAlist[,,2],applyAlist[,,3],applyAlist[,,4],applyAlist[,,5])
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
BIN
  • 781
  • 2
  • 10
  • 24
  • 1
    `sapply(1:5, function(i) list(table[,,i]))` FYI, `data.table` has nothing to do with `table` (I removed the tag) – Sotos Aug 29 '16 at 06:45
  • 1
    @Sotos, that's quick thanks a lot – BIN Aug 29 '16 at 06:47
  • 1
    Or you can use `lapply` i.e. `lapply(1:5, function(i) applyAlist[,,i])` – akrun Aug 29 '16 at 06:48
  • @akrun, so when we use lapply, not use list() – BIN Aug 29 '16 at 06:52
  • @BIN With `sapply`, the default option is `simplify = TRUE` so it could convert to a `matrix` if we don't change to `FALSE` (when the elements have the same length), but `lapply` always returns a `list`. – akrun Aug 29 '16 at 06:53
  • @Sotos, I tag data.table just want to know there is another way to use data.table package, not necessary just for data frame, so I can know both ways – BIN Aug 29 '16 at 06:57
  • 1
    If you are planning on using data.table methods then you should realize that the applyAlist object has 3 dimensions and data.tables only have 2. You should indicate how you expect to deal with that concern ... as a separate question. – IRTFM Aug 29 '16 at 06:59

2 Answers2

1

The most obvious way to do it,

sapply(1:5, function(i) list(applyAlist[,,i]))
Sotos
  • 51,121
  • 6
  • 32
  • 66
1

We can do this with lapply by looping through the sequence of the third dimension and subsetting the 'applyAlist' based on the sequence.

lapply(seq(dim(applyAlist)[3]), function(i) applyAlist[,,i])

As the OP wants a list output, lapply always gives that output. With sapply, the default option is simplify = TRUE so it would return a matrix or vector when the length of the elements are the same in case we did not change the option to simplify = FALSE. In cases where the list elements are of different classes, this will become more noticeable and is damaging.

lst <- list(a = 1:3, b = rep(letters[1:3], 2), c = 2:4)
lapply(lst, unique)
#$a
#[1] 1 2 3

#$b
#[1] "a" "b" "c"

#$c
#[1] 2 3 4

sapply(lst, unique)
#      a   b   c  
#[1,] "1" "a" "2"
#[2,] "2" "b" "3"
#[3,] "3" "c" "4"

but,

sapply(lst, unique, simplify = FALSE)
#$a
#[1] 1 2 3

#$b
#[1] "a" "b" "c"

#$c
#[1] 2 3 4

gives similar results as lapply as we changed the simplify

akrun
  • 874,273
  • 37
  • 540
  • 662