【问题标题】:assign random integer to each group in a dataframe为数据帧中的每个组分配随机整数
【发布时间】:2020-10-12 19:23:31
【问题描述】:

给定一个数据框,每个人都有三个不同的观察结果,我试图为每个唯一的人分配一个唯一的随机整数。 df <- data.frame(sample = 1:15, ID = rep(1:5, times = 3))

     sample ID
1       1  1
2       2  2
3       3  3
4       4  4
5       5  5
6       6  1
7       7  2
8       8  3
9       9  4
10     10  5
11     11  1
12     12  2
13     13  3
14     14  4
15     15  5

在这种情况下,我希望每个 ID 都有一个介于 1 和 5 之间的随机值“newvar”。

我试过了

df %>% group_by(ID) %>% mutate(newvar = sample(5, n(), replace = FALSE))

它不会在每个 ID 中保持新变量相同,并且

df %>% group_by(ID) %>% mutate(newvar = sample.int(n()))

在每组中给出一个介于 1 和 3 之间的随机数,并且

df %>% group_by(ID) %>% mutate(newvar = sample(5, replace = FALSE))

这不起作用,因为它希望 newvar 的大小为 1 或 3,而不是 5。

我也尝试过使用 ID 的级别:

levels(df$ID) 

这随机化了 ID 列并将其写入测试 df 上的 newvar

    sample ID newvar
1       1  5      5
2       2  2      2
3       3  1      1
4       4  4      4
5       5  3      3
6       6  5      5
7       7  2      2
8       8  1      1
9       9  4      4
10     10  3      3
11     11  5      5
12     12  2      2
13     13  1      1
14     14  4      4
15     15  3      3

在我的完整数据集(306 个人的 918 次观察)上,它会引发错误:

Error: Assigned data `value` must be compatible with existing data. x Existing data has 918 rows. x Assigned data has 306 rows. ℹ Only vectors of size 1 are recycled.

有没有办法让 sample() 在 group_by 命令中发生,或者让每个级别的 ID 正确分配给一个随机整数?

【问题讨论】:

    标签: r random group-by


    【解决方案1】:

    我们可以使用base Rsample 'ID' 的unique 值,然后在将名称设置为unique 'ID' 后与'ID' 匹配。当“ID”不是数字或不遵循从 1 开始的序列时,这也应该有效

    un1 <- unique(df$ID)
    df$newvar <- setNames(sample(un1), un1)[as.character(df$ID)]
    df
    #   sample ID newvar
    #1       1  1      4
    #2       2  2      2
    #3       3  3      3
    #4       4  4      5
    #5       5  5      1
    #6       6  1      4
    #7       7  2      2
    #8       8  3      3
    #9       9  4      5
    #10     10  5      1
    #11     11  1      4
    #12     12  2      2
    #13     13  3      3
    #14     14  4      5
    #15     15  5      1
    

    【讨论】:

    • 我们不需要为每个id分配相同的随机数吗?
    【解决方案2】:

    这个做我想做的事:首先将 ID 复制到 newvar,然后在各个级别上复制 sample()。

    df$ID <- as.factor(df$ID)
    df$newvar <- df$ID
    levels(df$newvar) <- sample(length(levels(df$newvar)))
    

    感谢您的意见!

    【讨论】:

    • 使用 levels() 得到了我想要的随机编号,但现在我想在每个 newvar 数字上加 40。如果我将因子转换回数字,我会丢失随机数;它只是从 40 开始按顺序编号。即使我先转换为字符,然后再转换为数字,也是一样的。有什么办法可以丢失这些数字的嵌入历史记录?
    • 啊哈! as.numeric(as.character(df$newvar)) 多合一命令可以解决问题!
    【解决方案3】:

    为了最符合您的想法,这会为 1 到 5 之间的每个 ID 分配一个一致的样本。

    df %>%
      group_by(ID) %>%
      mutate(newvar = sample(5, 1))
    

    【讨论】:

      【解决方案4】:

      用 ID 对长度为 5 的样本进行子集怎么样?

      df %>% mutate(newvar = sample(5)[ID])
      #>    sample ID newvar
      #> 1       1  1      4
      #> 2       2  2      5
      #> 3       3  3      3
      #> 4       4  4      2
      #> 5       5  5      1
      #> 6       6  1      4
      #> 7       7  2      5
      #> 8       8  3      3
      #> 9       9  4      2
      #> 10     10  5      1
      #> 11     11  1      4
      #> 12     12  2      5
      #> 13     13  3      3
      #> 14     14  4      2
      #> 15     15  5      1
      

      【讨论】:

        猜你喜欢
        • 2020-10-12
        • 1970-01-01
        • 2017-10-17
        • 1970-01-01
        • 1970-01-01
        • 2016-01-09
        • 2019-12-06
        • 2020-05-02
        • 1970-01-01
        相关资源
        最近更新 更多