Lisann
Lisann

Reputation: 5855

Combine rownames from different lists in a dataframe

I have a question about lists in R. I have a list within 16 list containing a list with variables like this:

x

[[1]]
  A  1   3
  B  4   2

[[2]]
  C  23  4
  D  9   22
  E  4   54

The A,B,C and D are rownames in the lists. Now I want to create a file that paste only the rownames in a dataframe. Each row in the dataframe contains 1 list in the total list.

A B 
C D E

Can anyone help me with this? I thought maybe someting like do.call(rbind, rownames(x))

EDIT! 05-08-2011

Is there a way to save the rownames list by list? So in the end there are no NA's in the data and the data is unequal?

Thank you all!

Upvotes: 1

Views: 2679

Answers (3)

Gavin Simpson
Gavin Simpson

Reputation: 174813

Making an assumption about the nature of x, if we use:

x <- list(matrix(c(1,4,3,2), ncol = 2, 
                 dimnames = list(c("A","B"), NULL)), 
          matrix(c(23,9,4,4,22,54), ncol = 2, 
                 dimnames = list(c("C","D","E"), NULL)))

which gives:

> x
[[1]]
  [,1] [,2]
A    1    3
B    4    2

[[2]]
  [,1] [,2]
C   23    4
D    9   22
E    4   54

Then

> lapply(x, rownames)
[[1]]
[1] "A" "B"

[[2]]
[1] "C" "D" "E"

seems the only plausible answer. Unless we pad the ("A","B") vector with something, we can't use a matrix or a data frame because the component lengths do not match. Hence one of the reasons the do.call() idea fails:

> do.call(rbind, rownames(x))
Error in do.call(rbind, rownames(x)) : second argument must be a list
> do.call(rbind, lapply(x, rownames))
     [,1] [,2] [,3]
[1,] "A"  "B"  "A" 
[2,] "C"  "D"  "E" 
Warning message:
In function (..., deparse.level = 1)  :
      number of columns of result is not a multiple of vector length (arg 1)

To pad the result with NA and get a data frame, we could do:

out <- lapply(x, rownames)
foo <- function(x, max, repl = NA) {
    if(length(x) == max)
        out <- x
    else {
        out <- rep(repl, max)
        out[seq_along(x)] <- x
    }
    out
}
out <- lapply(out, foo, max = max(sapply(out, length)))
(out <- do.call(rbind, out))

The last line gives:

> (out <- do.call(rbind, out))
     [,1] [,2] [,3]
[1,] "A"  "B"  NA  
[2,] "C"  "D"  "E"

If you want that nicely printed, then

> print(format(out), quote = FALSE)
     [,1] [,2] [,3]
[1,] A    B    NA  
[2,] C    D    E

is an option inside R.

Upvotes: 3

Richie Cotton
Richie Cotton

Reputation: 121077

Your sample data:

x <- list(
  matrix(c(1,4,3,2), nrow = 2, dimnames = list(LETTERS[1:2])),
  matrix(c(23,9,4,4,22,54), nrow = 3, dimnames = list(LETTERS[3:5]))
)

What you want:

unlist(lapply(x, rownames))

Or, if you are keen on do.call, then this is equivalent:

do.call(c, lapply(x, rownames))

Upvotes: 0

Nick Sabbe
Nick Sabbe

Reputation: 11956

This should do it:

lapply(x, function(curdfr){paste(rownames(curdfr))})

This results in a vector with each element the space-separated rownames of the elements of the list.

Upvotes: 1

Related Questions