将特定于列表的截止值应用于嵌套列表中的单个向量
Apply list-specific cutoff value to individual vectors in nested list
我有一个嵌套列表,have_list
。中间是一个包含四个整数向量的列表,a
、b
、c
、d
.
对于a
、b
、c
、d
,每个都有一个唯一的cutoff
值。当整数大于相关截止值时,我想找到第一个位置。
如果 a-d 具有相同的 cutoff
,我可以这样做:
rapply(have_list, function(x) which.max(x > cutoff), how = "list")
我的 具体问题 是如何在没有 for
循环的情况下尽可能使用 a-d 的相应截止值。我似乎无法在 Internet 或 SO 上找到任何东西,但如果我忽略了之前的问题,我深表歉意。
示例数据
cutoff <- c(a = 5, b = 17, c = 11, d = 7)
set.seed(05062020)
have_list <- list(Outer1 = list(a = sample(1:25, 10),
b = sample(1:25, 10),
c = sample(1:25, 10),
d = sample(1:25, 10)),
Outer2 = list(a = sample(1:25, 10),
b = sample(1:25, 10),
c = sample(1:25, 10),
d = sample(1:25, 10)))
需要的数据
want_list <- list(Outer1 = list(a = 2, b = 2, c = 1, d = 1),
Outer2 = list(a = 1, b = 4, c = 4, d = 1))
您可以使用 lapply
在“外部”列表中移动,并使用 Map
将每个内部列表与相应的截止值进行比较:
lapply(have_list, \(x) {Map(\(lst, cuts) {
return(which(lst > cuts)[1])
}, x, cutoff)})
这是此输出的 str
:
List of 2
$ Outer1:List of 4
..$ a: int 2
..$ b: int 2
..$ c: int 1
..$ d: int 1
$ Outer2:List of 4
..$ a: int 1
..$ b: int 4
..$ c: int 4
..$ d: int 1
这样的事情怎么样:
lapply(have_list, function(x) {
as.list(sapply(names(x), function(y) {
min(which(x[[y]]>cutoff[[y]]))
}))
})
输出:
$Outer1
$Outer1$a
[1] 2
$Outer1$b
[1] 2
$Outer1$c
[1] 1
$Outer1$d
[1] 1
$Outer2
$Outer2$a
[1] 1
$Outer2$b
[1] 4
$Outer2$c
[1] 4
$Outer2$d
[1] 1
另一种可能的解决方案,基于 purrr::map
和 purrr::map2
:
library(purrr)
map(have_list, ~ map2(.x, cutoff, ~ which.max(.x > .y)))
#> $Outer1
#> $Outer1$a
#> [1] 2
#>
#> $Outer1$b
#> [1] 2
#>
#> $Outer1$c
#> [1] 1
#>
#> $Outer1$d
#> [1] 1
#>
#>
#> $Outer2
#> $Outer2$a
#> [1] 1
#>
#> $Outer2$b
#> [1] 4
#>
#> $Outer2$c
#> [1] 4
#>
#> $Outer2$d
#> [1] 1
对于任意嵌套的列表,您还可以在rrapply
-package中使用rrapply()
,它可以访问正在评估的列表元素的名称:
library(rrapply)
want_list <- rrapply(have_list, f = \(x, .xname) which.max(x > cutoff[.xname]))
str(want_list)
#> List of 2
#> $ Outer1:List of 4
#> ..$ a: int 2
#> ..$ b: int 2
#> ..$ c: int 1
#> ..$ d: int 1
#> $ Outer2:List of 4
#> ..$ a: int 1
#> ..$ b: int 4
#> ..$ c: int 4
#> ..$ d: int 1
我有一个嵌套列表,have_list
。中间是一个包含四个整数向量的列表,a
、b
、c
、d
.
对于a
、b
、c
、d
,每个都有一个唯一的cutoff
值。当整数大于相关截止值时,我想找到第一个位置。
如果 a-d 具有相同的 cutoff
,我可以这样做:
rapply(have_list, function(x) which.max(x > cutoff), how = "list")
我的 具体问题 是如何在没有 for
循环的情况下尽可能使用 a-d 的相应截止值。我似乎无法在 Internet 或 SO 上找到任何东西,但如果我忽略了之前的问题,我深表歉意。
示例数据
cutoff <- c(a = 5, b = 17, c = 11, d = 7)
set.seed(05062020)
have_list <- list(Outer1 = list(a = sample(1:25, 10),
b = sample(1:25, 10),
c = sample(1:25, 10),
d = sample(1:25, 10)),
Outer2 = list(a = sample(1:25, 10),
b = sample(1:25, 10),
c = sample(1:25, 10),
d = sample(1:25, 10)))
需要的数据
want_list <- list(Outer1 = list(a = 2, b = 2, c = 1, d = 1),
Outer2 = list(a = 1, b = 4, c = 4, d = 1))
您可以使用 lapply
在“外部”列表中移动,并使用 Map
将每个内部列表与相应的截止值进行比较:
lapply(have_list, \(x) {Map(\(lst, cuts) {
return(which(lst > cuts)[1])
}, x, cutoff)})
这是此输出的 str
:
List of 2
$ Outer1:List of 4
..$ a: int 2
..$ b: int 2
..$ c: int 1
..$ d: int 1
$ Outer2:List of 4
..$ a: int 1
..$ b: int 4
..$ c: int 4
..$ d: int 1
这样的事情怎么样:
lapply(have_list, function(x) {
as.list(sapply(names(x), function(y) {
min(which(x[[y]]>cutoff[[y]]))
}))
})
输出:
$Outer1
$Outer1$a
[1] 2
$Outer1$b
[1] 2
$Outer1$c
[1] 1
$Outer1$d
[1] 1
$Outer2
$Outer2$a
[1] 1
$Outer2$b
[1] 4
$Outer2$c
[1] 4
$Outer2$d
[1] 1
另一种可能的解决方案,基于 purrr::map
和 purrr::map2
:
library(purrr)
map(have_list, ~ map2(.x, cutoff, ~ which.max(.x > .y)))
#> $Outer1
#> $Outer1$a
#> [1] 2
#>
#> $Outer1$b
#> [1] 2
#>
#> $Outer1$c
#> [1] 1
#>
#> $Outer1$d
#> [1] 1
#>
#>
#> $Outer2
#> $Outer2$a
#> [1] 1
#>
#> $Outer2$b
#> [1] 4
#>
#> $Outer2$c
#> [1] 4
#>
#> $Outer2$d
#> [1] 1
对于任意嵌套的列表,您还可以在rrapply
-package中使用rrapply()
,它可以访问正在评估的列表元素的名称:
library(rrapply)
want_list <- rrapply(have_list, f = \(x, .xname) which.max(x > cutoff[.xname]))
str(want_list)
#> List of 2
#> $ Outer1:List of 4
#> ..$ a: int 2
#> ..$ b: int 2
#> ..$ c: int 1
#> ..$ d: int 1
#> $ Outer2:List of 4
#> ..$ a: int 1
#> ..$ b: int 4
#> ..$ c: int 4
#> ..$ d: int 1