[R] Reduce(paste, x) question
Brian Diggs
diggsb at ohsu.edu
Tue Nov 6 22:11:17 CET 2012
On 11/1/2012 1:06 PM, mdvaan wrote:
> I should have been more specific:
>
> y <- list()
> a <- c("A", "K")
> b <- c("B", "L")
> c <- c("C", "M")
> d <- c("D", "N")
> e <- c("E", "O")
>
> y[[1]] <- a
> y[[2]] <- b
> y[[3]] <- c
> y[[4]] <- d
> y[[5]] <- e
>
> y
> [[1]]
> [1] "A" "K"
>
> [[2]]
> [1] "B" "L"
>
> [[3]]
> [1] "C" "M"
>
> [[4]]
> [1] "D" "N"
>
> [[5]]
> [1] "E" "O"
>
> How do I get a list object like y (each element of y is a vector of strings)
> from:
>
> x[[1]] <- LETTERS[1:5]
> x[[2]] <- LETTERS[11:15]
>
> using only the Reduce function?
>
> Thanks!
If you are not bound to use the Reduce function, then a simple approach
is just
library("plyr")
alply(do.call(cbind,x), 1)
If you need it to match in terms of names and everything, wrapping that
in and unclass and unname will give exactly y
> x
[[1]]
[1] "A" "B" "C" "D" "E"
[[2]]
[1] "K" "L" "M" "N" "O"
> y
[[1]]
[1] "A" "K"
[[2]]
[1] "B" "L"
[[3]]
[1] "C" "M"
[[4]]
[1] "D" "N"
[[5]]
[1] "E" "O"
> identical(y, unclass(unname(alply(do.call(cbind,x), 1))))
[1] TRUE
Now, if you _really_ want to use Reduce, you can. But it is trickier
because of the properties that the function used in Reduce must have.
Most specifically, the function used in Reduce must return a value which
has the same structure as it takes in its first argument. Its second
argument must have the structure of each piece of the variable being fed in.
In your case, the return value is a list of length equal to the original
vectors of each element of x. So the first argument to the function used
in Reduce must be a list. The second argument is a vector. The function
must add each element of the vector to the vector in the corresponding
position of the list.
bnd <- function(x1, x2) {
lapply(seq_along(x1), function(i) {
c(x1[[i]], x2[[i]])
})
}
Now this function can be used in the Reduce function, if an init value
is specified that acts as an identity under bnd and is of the correct
structure (list of appropriate length); a list of NULLs will work
Reduce(bnd, x, init=replicate(length(x[[1]]), NULL))
Both methods appropriately handle longer x's
> x[[3]] <- LETTERS[21:25]
> unclass(unname(alply(do.call(cbind,x), 1)))
[[1]]
[1] "A" "K" "U"
[[2]]
[1] "B" "L" "V"
[[3]]
[1] "C" "M" "W"
[[4]]
[1] "D" "N" "X"
[[5]]
[1] "E" "O" "Y"
> Reduce(bnd, x, init=replicate(length(x[[1]]), NULL))
[[1]]
[1] "A" "K" "U"
[[2]]
[1] "B" "L" "V"
[[3]]
[1] "C" "M" "W"
[[4]]
[1] "D" "N" "X"
[[5]]
[1] "E" "O" "Y"
The only reason that you _must_ use Reduce is that this is a homework
question, in which case I may have said too much.
> --
> View this message in context: http://r.789695.n4.nabble.com/Reduce-paste-x-question-tp4648151p4648169.html
> Sent from the R help mailing list archive at Nabble.com.
>
--
Brian S. Diggs, PhD
Senior Research Associate, Department of Surgery
Oregon Health & Science University
More information about the R-help
mailing list