我想要一个包含几个几乎相同的小标题的小标题。在每个嵌套的 tibble 中,一个变量的内容被打乱,其他的不变。我想要 N(例如 10)个版本的每个打乱的 tibble。
library(tidyverse)
df <- tibble(a = 1:5, b = 6:10, c = 11:15)
permutation_n <- 10
tbl_names <- names(df)
shuffle_var <- function(data, var) {
data %>%
mutate({{var}} := sample({{var}}))
}
> shuffle_var(df, a)
# A tibble: 5 × 3
a b c
<int> <int> <int>
1 4 6 11
2 2 7 12
3 1 8 13
4 3 9 14
5 5 10 15
shuffle_var()
如果我单独使用它可以正常工作。
但是如果我在
map()
里面使用它,它会返回一个tibble,原始变量不变,一个新的变量叫做.x
result <-
crossing(variable = tbl_names,
index = 1:permutation_n) %>%
mutate(data = map(variable, ~shuffle_var(df, .x)),
)
result %>% slice(1) %>% pull(data) %>% .[[1]]
# A tibble: 5 × 4
a b c .x
<int> <int> <int> <chr>
1 1 6 11 a
2 2 7 12 a
3 3 8 13 a
4 4 9 14 a
5 5 10 15 a
result
应包含 30 行(变量 x 版本)。
每个嵌套的 tibble 应该有 10 个不同的版本,其中一个变量的值被打乱)。
我在 SO 中找到了几个类似的例子,但它们都没有帮助解决这个特定问题。
在函数内用
.data
代词试试:
.data
是`map()``.data[[var]]
来引用想要的列 (var
),我们可以使用 map() 来迭代每个嵌套的 tibbleshuffle_var <- function(data, var) {
data %>%
mutate({{var}} := sample(.data[[var]]))
}
result <-
crossing(variable = tbl_names,
index = 1:permutation_n) %>%
mutate(data = map(variable, ~shuffle_var(df, .x))
)
result %>%
slice(1) %>% pull(data) %>% .[[1]]
a b c .x
<int> <int> <int> <int>
1 1 6 11 1
2 2 7 12 5
3 3 8 13 3
4 4 9 14 4
5 5 10 15 2
使用
pick
shuffle_var <- function(data, var) {
data %>%
mutate({{var}} := sample(pick(all_of(var))[[1]]))
}
-测试
out <- crossing(variable = tbl_names,
index = 1:permutation_n) %>%
mutate(data = map(variable, ~shuffle_var(df, .x))
)
> out$data[[1]]
# A tibble: 5 × 4
a b c .x
<int> <int> <int> <int>
1 1 6 11 3
2 2 7 12 2
3 3 8 13 1
4 4 9 14 5
5 5 10 15 4