r语言 - 基于对应向量的单个值的列表中数据框架的子集



我正在尝试有条件地在基于向量值的数据框架列表中子集data.frames。基本上,每当a > 0我想将相应的列表元素子集为具有那么多随机抽样的行。

# a list
l <- list( data.frame(x=1:5, y = 1:5),
data.frame(x= 11:15, y = 11:15),
data.frame(x=21:25, y = 21:25) )
# a vector
a <- c(3, 1,-2) 
# one possible permutation of the desired output
[[1]]
x y
1 1 1
2 3 3
3 5 5
[[2]]
x  y
1 13 13
[[3]]
x  y
1 21 21
2 22 22
3 23 23
4 24 24
5 25 25

我一直试图这样做与purrr::map_if()如下,但是我的函数只使用a的第一个值作为所有数据帧的行数。也就是说,列表的第一个和第二个元素都是3行的子集,但我希望第二个元素只有1行。

f <- function(x, count) {x[sample(nrow(x), count),]}
purrr::map_if(l, a > 0, f, count = a)

是否有一种方法来传递'a'的值为map_if()的每次迭代?或者其他的解决方案?

Map+ifelse的基数R

> Map(function(x, k) x[sample(nrow(x), ifelse(k > 0, k, nrow(x))), ], l, a)
[[1]]
x y
3 3 3
4 4 4
5 5 5
[[2]]
x  y
2 12 12
[[3]]
x  y
2 22 22
1 21 21
5 25 25
3 23 23
4 24 24

您可以使用以下解决方案。这里你实际上需要使用purrr::map2base::mapplybase::Map,因为你应该并行迭代两个向量或列表。

library(dplyr)
library(purrr)
map2(a, l, ~ if(.x > 0) {
.y %>% 
slice_sample(n = .x)
} else {
.y
})
[[1]]
x y
1 2 2
2 4 4
3 3 3
[[2]]
x  y
1 11 11
[[3]]
x  y
1 21 21
2 22 22
3 23 23
4 24 24
5 25 25
library(tidyverse)
# a list
l <- list( data.frame(x=1:5, y = 1:5),
data.frame(x= 11:15, y = 11:15),
data.frame(x=21:25, y = 21:25) )
# a vector
a <- c(3, 1, -2) 
map2(
.x = l,
.y = a,
.f = ~sample_n(tbl = .x, size = ifelse(.y > nrow(.x) | .y < 0, nrow(.x), .y))
)
#> [[1]]
#>   x y
#> 1 4 4
#> 2 2 2
#> 3 1 1
#> 
#> [[2]]
#>    x  y
#> 1 13 13
#> 
#> [[3]]
#>    x  y
#> 1 24 24
#> 2 21 21
#> 3 23 23
#> 4 22 22
#> 5 25 25

由reprex包(v2.0.1)于2021-09-10创建

最新更新