Access specific line of every matrix in list - r

This might be very trivial, but I haven't found an answer yet (and I'm quite new to R).
I have a list containing a bunch of matrices. Each matrix in the list has the same number of rows and rownames.
How to I access say, the second row of each matrix in the list?

Use lapply
x <-matrix(1:9, 3, dimnames=list(LETTERS[1:3], letters[24:26])) # creating a matrix
mylist <- list(x, 2*x, 3*x, 4*x) # creating the list
lapply(mylist, function(x) x['B',]) # By name
sapply(mylist, function(x) x['B',]) # alternative
lapply(mylist, function(x) x[2,]) # By index
sapply(mylist, function(x) x[2,])

Related

How do I take the mean of the same element across multiple lists?

I have many lists contained within a larger list. I want to take the mean of the same entry in each of the lists.
Since I have many lists (100 plus) I want to be able to take the mean of all these lists by using 1:100 like I would for vector entries.
Here is some example, non working code.
## Make two lists
list_1 <- list()
list_1[[1]] <- 2
list_2 <- list()
list_2[[1]] <- 4
##Make a larger list to put the lists in
big_list <- list()
## Add lists to a larger list
big_list[[1]] <- list_1
big_list[[2]] <- list_2
## This doesn't work
mean(big_list[[1]][1], big_list[[2]][1], na.rm=TRUE)
## This does not work, but it is what I want
mean(big_list[[1:2]][1])
You can use getElement inside sapply to pick out a vector comprising the first (or any specified) element from each sub-list:
sapply(big_list, getElement, 1)
#> [1] 2 4
and therefore
mean(sapply(big_list, getElement, 1))
#> [1] 3
We could combine flatten from purrr package with unlist:
library(purrr)
x <- unlist(flatten(big_list))
x
mean(x, na.rm = TRUE)
[1] 3
This approach will do it as well:
sapply(1:length(big_list[[1]]), function(i) mean(sapply(big_list, function(x) x[[i]]), na.rm = TRUE))

Transforming list obtained via strsplit to merge common categories

I have a list resembling the one below:
# Initial object
vec <- c("levelA-1", "levelA-2", "levelA-3",
"levelB-1", "levelB-2", "levelB-3")
lstVec <- strsplit(x = vec, split = "-")
I would like to arrive at a list of the following structure:
lstRes <- list(levelA = list(1:3),
lvelB = list(1:3))
Notes
The list has the following characteristics:
First level elements are transformed into distinct lists
Second level elements created via strsplit are elements of those lists
this suffices:
mat <- do.call(rbind, lstVec)
result <- split(mat[,2], mat[,1])
the do.call and rbind stack the result of lstVec by row into a matrix (thanks to G. Grothendieck for pointing out this is not a data frame), then the split split mat[,2] by mat[,1].
as Aaron says, ti is a little odd that you want nested list. but you can get it
lapply(result, as.list)
i am not sure how good rbind is. but another way to obtain mat is
mat <- matrix(unlist(lstVec), ncol = 2, byrow = TRUE)

Sort a matrix by columns with index return

I want to sort all the columns of a matrix A in R.
So far, I am using
apply(A,2,sort),
which gives sorted columns.
But I would also like to have the indexes of each column after sorting.
I tried to use index.return=TRUE as option of sort, but I think I can not use it in apply. How can I get the indexes?
We can also use index.return = TRUE, but when we have that, it will return a list.
lst <- apply(A,2,sort, index.return = TRUE)
If we need to convert it to a 3 column matrix with the column index as well
do.call(rbind, Map(cbind, colInd = seq_along(lst),
lapply(lst, function(x) do.call(cbind, x))))
data
set.seed(24)
A <- matrix(rnorm(25), 5, 5)

Nested named list to data frame

I have the following named list output from a analysis. The reproducible code is as follows:
list(structure(c(-213.555409754509, -212.033637890131, -212.029474755074,
-211.320398316741, -211.158815833294, -210.470525157849), .Names = c("wasn",
"chappal", "mummyji", "kmph", "flung", "movie")), structure(c(-220.119433774144,
-219.186901747536, -218.743319709963, -218.088361753899, -217.338920075687,
-217.186050877079), .Names = c("crazy", "wired", "skanndtyagi",
"andr", "unveiled", "contraption")))
I want to convert this to a data frame. I have tried unlist to data frame options using reshape2, dplyr and other solutions given for converting a list to a data frame but without much success. The output that I am looking for is something like this:
Col1 Val1 Col2 Val2
1 wasn -213.55 crazy -220.11
2 chappal -212.03 wired -219.18
3 mummyji -212.02 skanndtyagi -218.74
so on and so forth. The actual out put has multiple columns with paired values and runs into many rows. I have tried the following codes already:
do.call(rbind, lapply(df, data.frame, stringsAsFactors = TRUE))
works partially provides all the character values in a column and numeric values in the second.
data.frame(Reduce(rbind, df))
didn't work - provides the names in the first list and numbers from both the lists as tow different rows
colNames <- unique(unlist(lapply(df, names)))
M <- matrix(0, nrow = length(df), ncol = length(colNames),
dimnames = list(names(df), colNames))
matches <- lapply(df, function(x) match(names(x), colNames))
M[cbind(rep(sequence(nrow(M)), sapply(matches, length)),
unlist(matches))] <- unlist(df)
M
didn't work correctly.
Can someone help?
Since the list elements are all of the same length, you should be able to stack them and then combine them by columns.
Try:
do.call(cbind, lapply(myList, stack))
Here's another way:
as.data.frame( c(col = lapply(x, names), val = lapply(x,unname)) )
How it works. lapply returns a list; two lists combined with c make another list; and a list is easily coerced to a data.frame, since the latter is just a list of vectors having the same length.
Better than coercing to a data.frame is just modifying its class, effectively telling the list "you're a data.frame now":
L = c(col = lapply(x, names), val = lapply(x,unname))
library(data.table)
setDF(L)
The result doesn't need to be assigned anywhere with = or <- because L is modified "in place."

lapply: extract specific element

I have a list of subsets obtained through:
lapply(1:5, function(x) combn(5,x))
I would like to extract a specific vector from this list. For example, the 16th element of this list, which is (1,2,3). Any hints? Thanks.
The command produces all the subsets of (1,2,3,4,5), which is a list of 2^5=32 subsets. The 16th being (1,2,3). I want to know how to extract this by using its position (16th).
We could try by splitting (split) the matrix to a list of vectors for each list elements, concatenate c the output to flatten the list, and subset using the numeric index.
lst2 <- do.call(`c`,lapply(lst, function(x) split(x, col(x))))
lst2[[16]]
#[1] 1 2 3
Or instead of splitting the matrix output, we could use the FUN argument within combn to create list and then concatenate c using do.call
lst <- do.call(`c`,lapply(1:5, function(x) combn(5, x, FUN=list)))
lst[[16]]
#[1] 1 2 3
Or instead of do.call(c,..), we can use (contributed by #Marat Talipov)
lst <- unlist(lapply(1:5, function(x)
combn(5, x, FUN=list)), recursive=FALSE)
data
lst <- lapply(1:5, function(x) combn(5,x))
I would rather consider producing the right data instead of looping again on them :)
lst = Reduce('c', lapply(1:5, function(x) as.list(data.frame(combn(5,x)))))
> lst[[16]]
[1] 1 2 3

Resources