嵌套列表的条件子集
Conditional Subsetting of a Nested List
我有一个嵌套列表,其中每个子列表都有两个列表。此列表的简化输出如下:
nested.list <- list(`1` = structure(list(lengths = c(325L, 18L, 1L, 7L, 1L,
10L, 1L, 35L, 1L, 1L, 152L, 1L, 1L, 37L, 1L, 33L, 1L, 15L, 2L,
1L, 47L, 1L, 29L, 107L, 35L, 3L, 6L, 12L, 16L), values = c(1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 129,
1, 2, 1, 2, 1, 2, 1)), class = "rle"), `2` = structure(list(lengths = c(19L,
99L, 1L, 16L, 2L, 24L, 1L, 12L, 1L, 23L, 1L, 2L, 1L, 51L, 1L,
1L, 2L, 34L, 1L, 15L, 1L, 20L, 1L, 8L, 1L, 18L, 28L, 7L, 105L,
3L, 23L, 1L, 13L, 1L, 17L, 1L, 31L, 1L, 17L, 6L, 5L, 2L, 18L,
1L, 20L, 2L, 38L, 21L, 9L, 2L, 89L, 1L, 1L, 2L, 26L, 4L, 1L,
1L, 1L, 3L, 4L, 6L, 1L, 7L, 1L, 24L), values = c(1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 3, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 3, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2)), class = "rle"),
`3` = structure(list(lengths = c(6L, 3L, 14L, 1L, 1L, 1L,
1L, 1L, 9L, 2L, 29L, 3L, 11L, 1L, 19L, 1L, 20L, 1L, 2L, 1L,
22L, 11L, 2L, 1L, 7L, 2L, 17L, 30L, 3L, 1L, 1L, 1L, 8L, 4L,
5L, 1L, 23L, 1L, 11L, 4L, 2L, 1L, 29L, 2L, 10L, 1L, 17L,
6L, 12L, 1L, 22L, 22L, 8L, 3L, 2L, 13L, 1L, 1L, 1L, 83L,
1L, 24L, 1L, 24L, 1L, 7L, 6L, 4L, 1L, 2L, 1L, 37L, 1L, 32L,
33L, 5L, 1L, 29L, 6L, 7L, 16L, 2L, 16L, 1L, 1L, 1L, 3L, 1L,
18L, 1L, 9L, 4L, 3L, 1L, 21L, 14L, 12L, 1L, 33L), values = c(2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 1, 129, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2)), class = "rle"))
这是由 lapply(another.list, function(x) rle(x))
生成的,以防它很重要。
无论如何,我知道如何通过 nested.list[[1]]["lengths"]
之类的操作来提取单个元素。但是,我希望有条件地对每对列表进行子集化,以便我拥有所有 lengths >= 6
和 values == 2
。
我已经查找了以前的答案并找到了诸如 lapply(list,
[, list$value == 2)
之类的示例,但它们并未扩展到我的案例,而且我无法找到它们。
我想一定有一种我缺少的简单方法可以做到这一点。
这是一个基础 R 版本,returns data.frames。
lapply(nested.list,function(x){
y <- data.frame(lengths = x$length, values = x$values);
y[y$lengths >= 6 & y$values ==2,]})
#$`1`
# lengths values
#2 18 2
#4 7 2
#6 10 2
#...
#
#$`2`
# lengths values
#2 99 2
#4 16 2
#6 24 2
#...
#
#$`3`
# lengths values
#1 6 2
#3 14 2
#9 9 2
#...
也许,我们可以做到
lapply(nested.list, function(x) {
i1 <- x$lengths >=6 & x$values == 2
within.list(x, {lengths <- lengths[i1]; values <- values[i1]}) })
#$`1`
#Run Length Encoding
# lengths: int [1:9] 18 7 10 35 37 33 15 107 12
# values : num [1:9] 2 2 2 2 2 2 2 2 2
#$`2`
#Run Length Encoding
# lengths: int [1:23] 99 16 24 12 23 51 34 15 20 8 ...
# values : num [1:23] 2 2 2 2 2 2 2 2 2 2 ...
#$`3`
#Run Length Encoding
# lengths: int [1:33] 6 14 9 29 11 19 20 22 7 17 ...
# values : num [1:33] 2 2 2 2 2 2 2 2 2 2 ...
如果我们想在每个 list
中输出一个 data.frame
lapply(nested.list, function(x)
subset(as.data.frame(unclass(x)), lengths >=6 & values == 2))
将 nested.list
的 class 从 list
转换为 data.table
,并从数据表中提取子集值。
library('data.table')
nested.list <- rbindlist(lapply(seq_along(nested.list), function(x) {
y <- do.call('cbind.data.frame', nested.list[[x]])
y$id <- x
names(y) <- c('lengths', 'values', 'id')
y}
))
out <- nested.list[lengths >= 6 & values == 2, ]
head(out)
# lengths values id
# 1: 18 2 1
# 2: 7 2 1
# 3: 10 2 1
# 4: 35 2 1
# 5: 37 2 1
# 6: 33 2 1
我有一个嵌套列表,其中每个子列表都有两个列表。此列表的简化输出如下:
nested.list <- list(`1` = structure(list(lengths = c(325L, 18L, 1L, 7L, 1L,
10L, 1L, 35L, 1L, 1L, 152L, 1L, 1L, 37L, 1L, 33L, 1L, 15L, 2L,
1L, 47L, 1L, 29L, 107L, 35L, 3L, 6L, 12L, 16L), values = c(1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 129,
1, 2, 1, 2, 1, 2, 1)), class = "rle"), `2` = structure(list(lengths = c(19L,
99L, 1L, 16L, 2L, 24L, 1L, 12L, 1L, 23L, 1L, 2L, 1L, 51L, 1L,
1L, 2L, 34L, 1L, 15L, 1L, 20L, 1L, 8L, 1L, 18L, 28L, 7L, 105L,
3L, 23L, 1L, 13L, 1L, 17L, 1L, 31L, 1L, 17L, 6L, 5L, 2L, 18L,
1L, 20L, 2L, 38L, 21L, 9L, 2L, 89L, 1L, 1L, 2L, 26L, 4L, 1L,
1L, 1L, 3L, 4L, 6L, 1L, 7L, 1L, 24L), values = c(1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 3, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 3, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2)), class = "rle"),
`3` = structure(list(lengths = c(6L, 3L, 14L, 1L, 1L, 1L,
1L, 1L, 9L, 2L, 29L, 3L, 11L, 1L, 19L, 1L, 20L, 1L, 2L, 1L,
22L, 11L, 2L, 1L, 7L, 2L, 17L, 30L, 3L, 1L, 1L, 1L, 8L, 4L,
5L, 1L, 23L, 1L, 11L, 4L, 2L, 1L, 29L, 2L, 10L, 1L, 17L,
6L, 12L, 1L, 22L, 22L, 8L, 3L, 2L, 13L, 1L, 1L, 1L, 83L,
1L, 24L, 1L, 24L, 1L, 7L, 6L, 4L, 1L, 2L, 1L, 37L, 1L, 32L,
33L, 5L, 1L, 29L, 6L, 7L, 16L, 2L, 16L, 1L, 1L, 1L, 3L, 1L,
18L, 1L, 9L, 4L, 3L, 1L, 21L, 14L, 12L, 1L, 33L), values = c(2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 1, 129, 1, 2, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 1, 2,
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1,
2, 1, 2)), class = "rle"))
这是由 lapply(another.list, function(x) rle(x))
生成的,以防它很重要。
无论如何,我知道如何通过 nested.list[[1]]["lengths"]
之类的操作来提取单个元素。但是,我希望有条件地对每对列表进行子集化,以便我拥有所有 lengths >= 6
和 values == 2
。
我已经查找了以前的答案并找到了诸如 lapply(list,
[, list$value == 2)
之类的示例,但它们并未扩展到我的案例,而且我无法找到它们。
我想一定有一种我缺少的简单方法可以做到这一点。
这是一个基础 R 版本,returns data.frames。
lapply(nested.list,function(x){
y <- data.frame(lengths = x$length, values = x$values);
y[y$lengths >= 6 & y$values ==2,]})
#$`1`
# lengths values
#2 18 2
#4 7 2
#6 10 2
#...
#
#$`2`
# lengths values
#2 99 2
#4 16 2
#6 24 2
#...
#
#$`3`
# lengths values
#1 6 2
#3 14 2
#9 9 2
#...
也许,我们可以做到
lapply(nested.list, function(x) {
i1 <- x$lengths >=6 & x$values == 2
within.list(x, {lengths <- lengths[i1]; values <- values[i1]}) })
#$`1`
#Run Length Encoding
# lengths: int [1:9] 18 7 10 35 37 33 15 107 12
# values : num [1:9] 2 2 2 2 2 2 2 2 2
#$`2`
#Run Length Encoding
# lengths: int [1:23] 99 16 24 12 23 51 34 15 20 8 ...
# values : num [1:23] 2 2 2 2 2 2 2 2 2 2 ...
#$`3`
#Run Length Encoding
# lengths: int [1:33] 6 14 9 29 11 19 20 22 7 17 ...
# values : num [1:33] 2 2 2 2 2 2 2 2 2 2 ...
如果我们想在每个 list
lapply(nested.list, function(x)
subset(as.data.frame(unclass(x)), lengths >=6 & values == 2))
将 nested.list
的 class 从 list
转换为 data.table
,并从数据表中提取子集值。
library('data.table')
nested.list <- rbindlist(lapply(seq_along(nested.list), function(x) {
y <- do.call('cbind.data.frame', nested.list[[x]])
y$id <- x
names(y) <- c('lengths', 'values', 'id')
y}
))
out <- nested.list[lengths >= 6 & values == 2, ]
head(out)
# lengths values id
# 1: 18 2 1
# 2: 7 2 1
# 3: 10 2 1
# 4: 35 2 1
# 5: 37 2 1
# 6: 33 2 1