Reputation:
I have a list, and I am trying to choose a specific number from it. For example:
x <- list()
x[[1]] <- c(1,2,3)
x[[2]] <- c(4,5,6)
x[[3]] <- c(7,8,9)
Now I do this:
y <- combn(x,2)
y looks like this:
[,1] [,2] [,3]
[1,] Numeric,3 Numeric,3 Numeric,3
[2,] Numeric,3 Numeric,3 Numeric,3
A matrix is returned with columns representing each set. However, I want to concatenate them column-wise, but I cannot do so.
cbind(y)
[,1] [,2] [,3]
[1,] Numeric,3 Numeric,3 Numeric,3
[2,] Numeric,3 Numeric,3 Numeric,3
There should be only one row, but there are two! In addition, when I concatenate specific elements, this happens:
c(y[1,1],y[2,1])
[[1]]
[1] 1 2 3
[[2]]
[1] 4 5 6
This is just an example. The actual list is much larger. How can I accomplish this? Basically, I'm trying to do k-fold cross validation but each subset of the data is in a list.
Upvotes: 0
Views: 154
Reputation: 2270
Following your example, since your list is not of equal length, you can try this:
for(counter in i : ncol(y)){
newList[[counter]] <- do.call(c, y[1 : 2, counter]
}
Upvotes: 0
Reputation: 35314
We can take combinations of the list indexes, and for each combination combine the two corresponding list components into a vector.
To preserve the list structure we must pass simplify=F
to combn()
:
combn(seq_along(x),2L,function(i) c(x[[i[1L]]],x[[i[2L]]]),simplify=F);
## [[1]]
## [1] 1 2 3 4 5 6
##
## [[2]]
## [1] 1 2 3 7 8 9
##
## [[3]]
## [1] 4 5 6 7 8 9
##
Actually there's an even easier way to do it:
combn(x,2L,unlist,simplify=F);
## [[1]]
## [1] 1 2 3 4 5 6
##
## [[2]]
## [1] 1 2 3 7 8 9
##
## [[3]]
## [1] 4 5 6 7 8 9
##
Upvotes: 2
Reputation: 887108
We can use this within combn
itself as it has the FUN
argument.
combn(1:3, 2, FUN = function(i) list(do.call(cbind, x[i])))
#[[1]]
# [,1] [,2]
#[1,] 1 4
#[2,] 2 5
#[3,] 3 6
#[[2]]
# [,1] [,2]
#[1,] 1 7
#[2,] 2 8
#[3,] 3 9
#[[3]]
# [,1] [,2]
#[1,] 4 7
#[2,] 5 8
#[3,] 6 9
Upvotes: 1
Reputation: 43334
You can just make a matrix of indices with combn
and apply
across it, do.call(cbind, ...)
ing each pair. You'll need an extra list()
call so apply
doesn't simplify everything into one matrix:
apply(combn(1:3, 2), 2, function(i){list(do.call(cbind, x[i]))})
## [[1]]
## [[1]][[1]]
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
##
##
## [[2]]
## [[2]][[1]]
## [,1] [,2]
## [1,] 1 7
## [2,] 2 8
## [3,] 3 9
##
##
## [[3]]
## [[3]][[1]]
## [,1] [,2]
## [1,] 4 7
## [2,] 5 8
## [3,] 6 9
The elements are annoyingly nested, but a purrr::flatten()
call neatens the structure easily enough.
Upvotes: 0
Reputation: 1365
From your question I think what you want is to make each list a column in a matrix. Please correct your question if this is not the case.
What you want to use is do.call(). I recommend looking at the documentation for this function (?do.call
) - but briefly it executes a function on a list.
x <- list()
x[[1]] <- c(1,2,3)
x[[2]] <- c(4,5,6)
x[[3]] <- c(7,8,9)
do.call(cbind, x)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
Upvotes: 1