Adding lists together with a loop

Viewed 23

I'm trying to add lists together using a loop. Here is some example data.

df <- data.frame(var1 = c(1,1,2,2,2,2,3,3,3,3,3), var2= 1:11)
> df
   var1 var2
1     1    1
2     1    2
3     2    3
4     2    4
5     2    5
6     2    6
7     3    7
8     3    8
9     3    9
10    3   10
11    3   11

I've run this loop code, and would like the items to be stored in a file that contains 3 lists

list_container <- list()
for (i in  unique(df$var1) ) {
  templist <-  df[ df$var1==i , "var2"] 
  list_container <- list(list_container, templist)
}

it doesn't work, and ends up looking like this

> list_container
[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
list()

[[1]][[1]][[2]]
[1] 1 2

[[1]][[2]]
[1] 3 4 5 6

[[2]]
[1]  7  8  9 10 11

I want the 3 sets of list to sit separately, it should end up like this

list_result <- list(1:2, 3:6, 7:11)
> list_result
[[1]]
[1] 1 2

[[2]]
[1] 3 4 5 6

[[3]]
[1]  7  8  9 10 11

Is there anyway I can modify my code to get the desired result? Any help greatly appreciated. Thanks

3 Answers

split would be more direct and faster

with(df, unname(split(var2, var1)))

-output

[[1]]
[1] 1 2

[[2]]
[1] 3 4 5 6

[[3]]
[1]  7  8  9 10 11

If we want to use the == with unique elements, initialize with a NULL list of length same as the length of unique elements of 'var1' column. Loop over the sequence of unique elements, and assign the subset of 'var2' to the ith element of 'list_container'

un1 <- unique(df$var1)
list_container <- vector('list', length(un1))
for(i in seq_along(un1)) 
    list_container[[i]] <- df$var2[df$var1 == un1[i]]

-output

list_container
[[1]]
[1] 1 2

[[2]]
[1] 3 4 5 6

[[3]]
[1]  7  8  9 10 11

Another base R option using tapply

> with(df, tapply(var2, var1, c))
$`1`
[1] 1 2

$`2`
[1] 3 4 5 6

$`3`
[1]  7  8  9 10 11

or aggregate

> aggregate(var2 ~ ., df, c)$var2
[[1]]
[1] 1 2

[[2]]
[1] 3 4 5 6

[[3]]
[1]  7  8  9 10 11

You could also use unstack:

unstack(df, var2~var1)
$`1`
[1] 1 2

$`2`
[1] 3 4 5 6

$`3`
[1]  7  8  9 10 11

if you do not want the names, you can get rid of them:

unname(unstack(df, var2~var1))
[[1]]
[1] 1 2

[[2]]
[1] 3 4 5 6

[[3]]
[1]  7  8  9 10 11
Related