How to Directly Select the Same Column from All Nested Lists Within a List

How to directly select the same column from all nested lists within a list?

Assuming you have something like the following:

myList <- list(`0` = c(`1` = 10, `2` = 20, `3` = 30, `4` = 72),
`1` = c(`1` = 15, `2` = 9, `3` = 7))
myList
# $`0`
# 1 2 3 4
# 10 20 30 72
#
# $`1`
# 1 2 3
# 15 9 7

Use sapply() or lapply() to get into your list and extract whatever columns you want. Some examples.

# As a list of one-column data.frames
lapply(myList, `[`, 1)
# $`0`
# 1
# 10
#
# $`1`
# 1
# 15

# As a list of vectors
lapply(myList, `[[`, 1)
# $`0`
# [1] 10
#
# $`1`
# [1] 15

# As a named vector
sapply(myList, `[[`, 1)
# 0 1
# 10 15

# As an unnamed vector
unname(sapply(myList, `[[`, 1))
# [1] 10 15

Other variants of the syntax that also get you there include:

## Same output as above, different syntax
lapply(myList, function(x) x[1])
lapply(myList, function(x) x[[1]])
sapply(myList, function(x) x[[1]])
unname(sapply(myList, function(x) x[[1]]))

A Nested List Example

If you do have nested lists (lists within lists), try the following variants.

# An example nested list
myNestedList <- list(A = list(`0` = c(`1` = 10, `2` = 20, `3` = 30, `4` = 72),
`1` = c(`1` = 15, `2` = 9, `3` = 7)),
B = list(`0` = c(A = 11, B = 12, C = 13),
`1` = c(X = 14, Y = 15, Z = 16)))

# Run the following and see what you come up with....
lapply(unlist(myNestedList, recursive = FALSE), `[`, 1)
lapply(unlist(myNestedList, recursive = FALSE), `[[`, 1)
sapply(unlist(myNestedList, recursive = FALSE), `[[`, 1)
rapply(myNestedList, f=`[[`, ...=1, how="unlist")

Note that for lapply() and sapply() you need to use unlist(..., recursive = FALSE) while for rapply() (recursive apply), you refer to the list directly.

Extract multiple columns from nested lists (using object prefix)

You can try:

sapply(mylist[grep("^(t|b)\\.out", names(mylist))],
function(x) unlist(x[startsWith(names(x), "col")], use.names = FALSE))
# t.out1 t.out2 b.out3
# [1,] -0.6741380 0.4457036 0.09194051
# [2,] 0.8463555 -1.0284650 0.23858507
# [3,] -1.9122132 0.9740014 -0.16088752
# [4,] -1.4880384 -0.2844162 2.32278847
# [5,] 0.6463312 -0.4652480 -1.04187252
# [6,] -1.2264961 0.7801192 -0.83594572
# [7,] 0.4658511 -0.7364893 -0.75425093
# [8,] 1.7240282 -1.4285961 1.97459931
# [9,] 0.6239692 -0.6896502 -1.64462726
#[10,] -1.0699496 0.3033302 0.34368145

with mylist[grep("^(t|b)\\.out", names(mylist))] I select those starting with t.out or b.out. With startsWith(names(x), "col") I get those staring with col.

Subsetting nested lists within R

I'm not exactly sure what you're expected output is supposed to be like, but perhaps something like this?

library(tidyverse)
unlist(mylist) %>%
data.frame(val = .) %>%
rownames_to_column("id") %>%
filter(str_detect(id, "(x|y1|y2)")) %>%
separate(id, into = c("id", "col"), sep = "\\.(?=\\w+$)") %>%
spread(col, val)
# id x y1 y2
#1 file1.sample1 2 1 2
#2 file1.sample1.sample2 4 3 8
#3 file2.sample1 6 6 4
#4 file2.sample1.sample2 6 7 4

How to permute a function in nested list in R?


library(tidyr)
library(purrr)
library(dplyr)

# create a nested data frame where we have created 10 lists
# for rows 1..10, 11..20, etc
df <- list_to_split %>%
mutate(row_id = (row_number()-1) %/% 10 + 1) %>%
group_by(row_id) %>%
nest()

# create cartesian product
crossing(a = df, b = df) %>%

# compute gdist for each combo
mutate(gdist = map2(a$data, b$data, gower::gower_dist)) %>%

# compute avg value for each
mutate(gavg = map_dbl(gdist, mean)) %>%

# order
arrange(-gavg)

Using mapply to select from elements from a nested list using multiple arguments

Try this. It is better to use a function to catch the desired values. The reason why you got an error is because functions works different when using indexing. It is better to set the function directly inside the *apply() sketch to reach the desired outcome. Here the code:

#Code
unlist(mapply(function(x,y) x[y],x=list1,y=list2))

Output:

[1]  4  8  5  8 15 17 12 15  3 15

Or if you want the output in a list:

#Code 2
List <- mapply(function(x,y) x[y],x=list1,y=list2)

Output:

List
[[1]]
[1] 4

[[2]]
[1] 8

[[3]]
[1] 5

[[4]]
[1] 8

[[5]]
[1] 15

[[6]]
[1] 17

[[7]]
[1] 12

[[8]]
[1] 15

[[9]]
[1] 3

[[10]]
[1] 15

Another simplified options can be (Many thanks and all credit to @27ϕ9):

#Code3
mapply(`[[`, list1, list2)

Output:

[1]  4  8  5  8 15 17 12 15  3 15

Or:

#Code4
mapply(`[`, list1, list2)

Output:

[[1]]
[1] 4

[[2]]
[1] 8

[[3]]
[1] 5

[[4]]
[1] 8

[[5]]
[1] 15

[[6]]
[1] 17

[[7]]
[1] 12

[[8]]
[1] 15

[[9]]
[1] 3

[[10]]
[1] 15


Related Topics



Leave a reply



Submit