基于相应向量的单个值的列表中的子集数据帧
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::map2
或 base::mapply
或 base::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 创建
我正在尝试根据向量中的值有条件地对 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::map2
或 base::mapply
或 base::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 创建