[R] Reshaping matrix of vectors as dataframe
David Winsemius
dwinsemius at comcast.net
Sun Jan 31 18:47:21 CET 2010
On Jan 31, 2010, at 9:53 AM, Oliver Gondring wrote:
> Dear R people,
>
> I have to deal with the output of a function which comes as a matrix
> of vectors.
If that is so, then the object below does not represent it, because
that is a matrix of _lists_.
> You can reproduce the structure as given below:
>
> x <- list(c(1,2,4),c(1,3,5),c(0,1,0),
> c(1,3,6,5),c(3,4,4,4),c(0,1,0,1),
> c(3,7),c(1,2),c(0,1))
> data <- matrix(x,byrow=TRUE,nrow=3)
> colnames(data) <- c("First", "Length", "Value")
> rownames(data) <- c("Case1", "Case2", "Case3")
>
> > data
> First Length Value
> Case1 Numeric,3 Numeric,3 Numeric,3
> Case2 Numeric,4 Numeric,4 Numeric,4
> Case3 Numeric,2 Numeric,2 Numeric,2
>
> > data["Case1",]
> $First
> [1] 1 2 4
>
> $Length
> [1] 1 3 5
>
> $Value
> [1] 0 1 0
> --------------------
>
> My goal now is to break the three vectors of each row of the matrix
> into their elements, assigning each element to a certain
> "Sequence" (which I want to be numbered according to the position of
> the corresponding values within the vectors), reshaping the whole as
> a data frame like this:
This is close to what you specify:
> apply(data, 1, function(.x) cbind(1:length(.x$First), sapply(.x,
function(.y) return(.y ) ) ) )
$Case1
First Length Value
[1,] 1 1 1 0
[2,] 2 2 3 1
[3,] 3 4 5 0
$Case2
First Length Value
[1,] 1 1 3 0
[2,] 2 3 4 1
[3,] 3 6 4 0
[4,] 4 5 4 1
$Case3
First Length Value
[1,] 1 3 1 0
[2,] 2 7 2 1
And if you do.call(rbind, on the result you would get a matrix but
loose the case labeling.
Adding the Case labels proved to be a bit of a challenge to me. Maybe
one of the wizards will take pity on us:
> sapply(rownames(data), function(.x) cbind(.x,
# those were the rownames
cbind(1:length(data[.x, "First"][[1]]),
# and that was the incremental counter
sapply(data[.x, ],
#and finally the values which unfortunately get turned into characters
function(.y) return(.y ) ) ) ) )
$Case1
.x First Length Value
[1,] "Case1" "1" "1" "1" "0"
[2,] "Case1" "2" "2" "3" "1"
[3,] "Case1" "3" "4" "5" "0"
$Case2
.x First Length Value
[1,] "Case2" "1" "1" "3" "0"
[2,] "Case2" "2" "3" "4" "1"
[3,] "Case2" "3" "6" "4" "0"
[4,] "Case2" "4" "5" "4" "1"
$Case3
.x First Length Value
[1,] "Case3" "1" "3" "1" "0"
[2,] "Case3" "2" "7" "2" "1"
(I tried a couple of plyr efforts but that is not a package that I
have had much success with.)
--
David.
>
> Case Sequence First Length Value
>
> Case1 1 1 1 0
> Case1 2 2 3 1
> Case1 3 4 5 0
>
> Case2 1 1 3 0
> Case2 2 3 4 1
> Case2 3 6 4 0
> Case2 4 5 4 1
>
> Case3 1 3 1 0
> Case3 2 7 2 1
>
> I suspect that there might be an elegant and not too complicated way
> to do this with one or several of the functions provided by the
> 'reshape' package, but due to my lack of experience with R in
> general, this package in particular and the complexity of the task I
> wasn't able to figure out how to do it so far.
>
> Every hint or helpful comment is much appreciated!
>
> Oliver
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
David Winsemius, MD
Heritage Laboratories
West Hartford, CT
More information about the R-help
mailing list