1

I'm trying to write a function (stackDataInList) to stack the data frame together, but having trouble to do so, some help is very appreciated

>datList
[[1]]
ID value
1 a 0.9101742
2 b 0.3841854
3 c 1.6821761
[[2]]
ID value
1 d -0.6357365
2 e -0.4616447
[[3]]
ID value
1 f 1.4322822
2 g -0.6506964
3 h -0.2073807
4 i -0.3928079
[[4]]
ID value
1 j -0.3199929
2 k -0.2791133
3 l 0.4941883

dataList looks like it

So basically I need to create a function, and when I will call it I'll get results below:

>stackDataInList(datList[1])
ID value
1 a 0.9101742
2 b 0.3841854
3 c 1.6821761
OR:
>stackDataInList(datList[c(1,3,4)])
ID value
1 a 0.9101742
2 b 0.3841854
3 c 1.6821761
4 f 1.4322822
5 g -0.6506964
6 h -0.2073807
7 i -0.3928079
8 j -0.3199929
9 k -0.2791133
10 l 0.4941883
Akshit
  • 424
  • 4
  • 15
  • 1
    `do.call('rbind', datList)` probably should do the work, or you can use `dplyr::bind_rows(datList)` – PKumar Jun 23 '19 at 05:21

2 Answers2

2

There are a number of ways you can do this. The fastest way (especially for large data frames) is to use rbindlist() function for the data.table package:

library(data.table)
datList <- list( data.frame(ID=c("a","b","c"), value=c(0.9101742,0.3841854, 1.6821761)),
             data.frame(ID=c("d","e"), value=c(-0.6357365,-0.4616447)),
             data.frame(ID=c("f","g","e"), value=c(1.4322822,-0.6506964,-0.2073807)))


rbindlist(datList)
#   ID      value
#1:  a  0.9101742
#2:  b  0.3841854
#3:  c  1.6821761
#4:  d -0.6357365
#5:  e -0.4616447
...

Or subsetting the list:

rbindlist(datList[c(1,3)])
#    ID      value
# 1:  a  0.9101742
# 2:  b  0.3841854
# 3:  c  1.6821761
# 4:  f  1.4322822
# 5:  g -0.6506964
# 6:  e -0.2073807
Katia
  • 3,784
  • 1
  • 14
  • 27
  • @BonaguidiLab It is not clear what is the meaning of the argument `a` in your function (you list it as a second argument, but then you are using it as a local variable in your function). In addition to this your approach to start with an empty list and then use `rbind()` function to add new rows will be very slow. It is still not clear why the above answer does not work for you. Are you trying to implement this function yourself? – Katia Jun 23 '19 at 06:13
1

As @PKumar pointed out in comments, in base R we may use do.call(rbind). Just put it into a function.

stackDataInList <- function(x) {
  return(do.call(rbind, x))
}

stackDataInList(L[1])  
#   ID     value
# 1  a 0.9101742
# 2  b 0.3841854
# 3  c 1.6821761

stackDataInList(L[c(1, 3, 4)])  
#    ID      value
# 1   a  0.9101742
# 2   b  0.3841854
# 3   c  1.6821761
# 4   f  1.4322822
# 5   g -0.6506964
# 6   h -0.2073807
# 7   i -0.3928079
# 8   j -0.3199929
# 9   k -0.2791133
# 10  l  0.4941883

Or use stack and mapply:

stackDataInList2 <- function(x) setNames(cbind.data.frame(stack(mapply(`[`, x, 1))[[1]],
                                                          stack(mapply(`[`, x, 2))[[1]]), 
                                         names(x[[1]]))

stackDataInList2(L[1])  
# ID     value
# 1  a 0.9101742
# 2  b 0.3841854
# 3  c 1.6821761
stackDataInList2(L[c(1, 3, 4)])  
# ID      value
# 1   a  0.9101742
# 2   b  0.3841854
# 3   c  1.6821761
# 4   f  1.4322822
# 5   g -0.6506964
# 6   h -0.2073807
# 7   i -0.3928079
# 8   j -0.3199929
# 9   k -0.2791133
# 10  l  0.4941883

Also Reduce is an option, found here

stackDataInList3 <- function(x) Reduce(rbind, x)
stackDataInList3(L[1])  
#   ID     value
# 1  a 0.9101742
# 2  b 0.3841854
# 3  c 1.6821761
stackDataInList3(L[c(1, 3, 4)]) 
#    ID      value
# 1   a  0.9101742
# 2   b  0.3841854
# 3   c  1.6821761
# 4   f  1.4322822
# 5   g -0.6506964
# 6   h -0.2073807
# 7   i -0.3928079
# 8   j -0.3199929
# 9   k -0.2791133
# 10  l  0.4941883

Data

L <- list(structure(list(ID = c("a", "b", "c"), value = c(0.9101742, 
0.3841854, 1.6821761)), row.names = c(NA, -3L), class = "data.frame"), 
    structure(list(ID = c("d", "e"), value = c(-0.6357365, -0.4616447
    )), row.names = c(NA, -2L), class = "data.frame"), structure(list(
        ID = c("f", "g", "h", "i"), value = c(1.4322822, -0.6506964, 
        -0.2073807, -0.3928079)), row.names = c(NA, -4L), class = "data.frame"), 
    structure(list(ID = c("j", "k", "l"), value = c(-0.3199929, 
    -0.2791133, 0.4941883)), row.names = c(NA, -3L), class = "data.frame"))
jay.sf
  • 60,139
  • 8
  • 53
  • 110