将特定于列表的截止值应用于嵌套列表中的各个向量

发布于 2025-01-16 03:20:17 字数 1204 浏览 0 评论 0原文

我有一个嵌套列表,have_list。中心是一个包含四个整数向量的列表:abcd

对于 abcd,每个都有一个唯一的 cutoff 值。我想找到当整数大于相关截止值时的第一个位置。

如果广告具有相同的截止,我可以通过以下方式执行此操作:

rapply(have_list, function(x) which.max(x > cutoff), how = "list")

我的具体问题是如何在没有 for 循环的情况下使用广告的相应截止值, 如果可能的话。我似乎在互联网上找不到任何东西,但如果我忽略了之前的问题,我深表歉意。

样本数据

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))

I have a nested list, have_list. At the center is a list with four vectors of integers, a, b, c, d.

For a, b, c, d, each has a unique cutoff value. I would like to find the first positions when the integer is greater than the relevant cutoff value.

I can do this if a-d had the same cutoff by:

rapply(have_list, function(x) which.max(x > cutoff), how = "list")

My specific question is how to use the respective cutoff values for a-d, without for loops, if possible. I can't seem to find anything on the internet or SO, though apologies if I overlooked a previous question.

Sample data

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)))

Desired data

want_list <- list(Outer1 = list(a = 2, b = 2, c = 1, d = 1),
                  Outer2 = list(a = 1, b = 4, c = 4, d = 1))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

人事已非 2025-01-23 03:20:18

您可以使用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

You can use lapply to move through the "Outer" lists, and Map to compare each inner list to the corresponding cutoff:

lapply(have_list, \(x) {Map(\(lst, cuts) {
  return(which(lst > cuts)[1])
}, x, cutoff)})

Here is the str of this output:

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
呢古 2025-01-23 03:20:18

像这样的东西怎么样:

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

How about something like this:

lapply(have_list, function(x) {
  as.list(sapply(names(x), function(y) {
    min(which(x[[y]]>cutoff[[y]]))
  }))
})

Output:

$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
岁月静好 2025-01-23 03:20:18

另一种可能的解决方案基于 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

Another possible solution, based on purrr::map and 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
喜你已久 2025-01-23 03:20:18

对于任意嵌套的列表,您还可以在 rrapply 包中使用 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

For abritrarily nested lists, you can also use rrapply() in the rrapply-package, which can access the name of the list element under evaluation:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文