使用 sample() 根据其他变量的水平创建新变量

Using sample() to create a new variable based on levels of other variables

考虑一下这个 df(我正在使用的那个要大得多)

set.seed(13)
test <- tibble(A = as.factor(seq(1:10)),
               B = as.factor(sample(c("Apple", "Banana"), 10, replace = T)),
               C = as.factor(sample(c("Cut", "Mashed"), 10, replace = T)),
               D = as.factor(sample(seq(1:3), 10, replace = T)))

我需要创建另一个数值变量,但新变量的数据需要与其他变量的水平相同。让我举例说明。

当我这样做时,或者我试图找到的任何其他方法

test %>%
  group_by(B,C,D) %>%
  mutate(E = sample(seq(0.01:100, 0.01), 10, replace = T))

我收到一条错误消息,

我想要的结果如下,我需要使用示例或随机生成器函数

         A     B      C      D       E
>      <fct>   <fct>  <fct>  <fct> <fct> 
>      1 1     Banana Mashed 3    0.2
>      2 2     Apple  Cut    1    4
>      3 3     Banana Mashed 1    5
>      4 4     Apple  Mashed 2    3
>      5 5     Banana Cut    1    1.3
>      6 6     Apple  Cut    3    4.7
>      7 7     Banana Mashed 1    5
>      8 8     Banana Mashed 1    5
>      9 9     Banana Cut    3    3.2
>     10 10    Banana Cut    3    3.2

因此第 9 行和第 10、3、7 和 8 行需要完全相同,因为某些变量 (B、C、D) 的水平相同

知道怎么做吗?

如果我没理解错的话,你想要这样的东西。基本上,您想根据因子组的不同值创建新列,然后将其重新加入,以便它们都具有相同的值。

library(dplyr)

new_values <- test %>% 
  distinct(B, C, D) %>% 
  mutate(E = sample(seq(0.01, 100, 0.01), n(), replace = T)) 

test %>%
  left_join(new_values, by = c("B", "C", "D"))
# # A tibble: 10 x 5
#    A    B       C      D        E
# <fct>    <fct>  <fct>  <fct>   <dbl>
#  1 1     Banana Mashed 3       68.0 
#  2 2     Apple  Cut    1       16.4 
#  3 3     Banana Mashed 1       80.2 
#  4 4     Apple  Mashed 2       74.4 
#  5 5     Banana Cut    1       1.53
#  6 6     Apple  Cut    3       27.8 
#  7 7     Banana Mashed 1       80.2 
#  8 8     Banana Mashed 1       80.2 
#  9 9     Banana Cut    3       83.4 
# 10 10    Banana Cut    3       83.4 

您也可以使用 group_modify() 执行类似的操作,但它会根据组对行进行排序并重新排列列。此代码将遍历每个组,根据大小为 1 的样本添加一列 E,然后将所有结果组重新堆叠回数据框中。

test %>% 
  group_by(B, C, D) %>% 
  group_modify(~ mutate(.x, E = sample(seq(0.01, 100, 0.01), 1, replace = T)))