基于相应向量的单个值的列表中的子集数据帧

Subset dataframes in a list based on a single value of a corresponding vector

我正在尝试根据向量中的值有条件地对 data.frames 列表中的 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 的第一个值作为所有 data.frames 的行数。也就是说,列表的第一个和第二个元素是 3 行的子集,但我希望第二个元素只有 1 行。

f <- function(x, count) {x[sample(nrow(x), count),]}

purrr::map_if(l, a > 0, f, count = a)

有没有办法为 map_if() 的每次迭代传递 'a' 中的值? 或者其他一些解决方案?

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

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

一个基础 R 一个 Map + ifelse

> 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
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 package (v2.0.1)

于 2021-09-10 创建