在R中通过id生成一个随机变量

Generate a random variable by id in R

我想根据实际 ID 创建一个随机 ID 变量。这意味着具有相同 ID 的观察必须具有相同的随机 ID。让我举个例子:

id  var1var2
1   a   1
5   g   35
1   hf  658
2   f   576
9   d   54546
2   dg  76
3   g   5
3   g   5
5   gg  56
6   g   456
8v  g   6
9   e   778795

预期结果是:

id  var1var2id random
1   a   1   9
5   g   35  1
1   hf  658 9
2   f   576 8
9   d   54546   3
2   dg  76  8
3   g   5   7
3   g   5   7
5   gg  56  1
6   g   456 5
8v  g   6   4
9   e   778795  3

要按组创建新 ID,请使用 matchsample,或 cur_group_id in dplyr。 ids将从1开始,直到达到总组数。

基础 R

dat$random_id <- match(dat$id, sample(unique(dat$id)))

dplyr

library(dplyr)
dat %>%
  group_by(id = factor(id, levels = sample(unique(id)))) %>%
  mutate(random_id = cur_group_id())

输出

   id    var1    var2 random_id
 1 1     a          1         6
 2 5     g         35         2
 3 1     hf       658         6
 4 2     f        576         4
 5 9     d      54546         5
 6 2     dg        76         4
 7 3     g          5         7
 8 3     g          5         7
 9 5     gg        56         2
10 6     g        456         1
11 8     g          6         3
12 9     e     778795         5

这是 ave 的基本 R 方式。
随机数在 1nrow(dat) 之间抽取。设置函数 sample 参数 size = 1 保证所有随机数都等于 id.

set.seed(2022)
dat$random <- with(dat, ave(id, id, FUN = \(x) sample(nrow(dat), size = 1)))

reprex package (v2.0.1)

创建于 2022-03-01

每个id只有一个random号码。

split(data.frame(id = dat$id, random = dat$random), dat$id)
#> $`1`
#>   id random
#> 1  1      4
#> 3  1      4
#> 
#> $`2`
#>   id random
#> 4  2      3
#> 6  2      3
#> 
#> $`3`
#>   id random
#> 7  3      7
#> 8  3      7
#> 
#> $`5`
#>   id random
#> 2  5     11
#> 9  5     11
#> 
#> $`6`
#>    id random
#> 10  6      4
#> 
#> $`8v`
#>    id random
#> 11 8v      6
#> 
#> $`9`
#>    id random
#> 5   9     12
#> 12  9     12

reprex package (v2.0.1)

创建于 2022-03-01

并且随机数是均匀分布的。重复上面的过程10000次,table结果画个条形图看看。

zz <- replicate(10000,
                with(dat, ave(id, id, FUN = \(x) sample(nrow(dat), size = 1))))
barplot(table(as.integer(zz)))

reprex package (v2.0.1)

创建于 2022-03-01

数据

dat <- read.table(header = T, text = "id  var1 var2
1   a   1
5   g   35
1   hf  658
2   f   576
9   d   54546
2   dg  76
3   g   5
3   g   5
5   gg  56
6   g   456
8v  g   6
9   e   778795")

reprex package (v2.0.1)

创建于 2022-03-01

只需为 id 创建一个随机组 ID 并合并到原始数据。

library(data.table)
library(tidyverse)
dt <- fread("
id  var1 var2
1   a   1
5   g   35
1   hf  658
2   f   576
9   d   54546
2   dg  76
3   g   5
3   g   5
5   gg  56
6   g   456
8v  g   6
9   e   778795        
            ")
uq <- unique(dt$id)
set.seed(1)
uqid <- sample(1:length(unique(dt$id)), replace = F)

dt1 <- data.table(id = uq , random = uqid)

left_join(dt, dt1, by = "id" )

> left_join(dt, dt1, by = "id" )
    id var1   var2 random
 1:  1    a      1      1
 2:  5    g     35      4
 3:  1   hf    658      1
 4:  2    f    576      7
 5:  9    d  54546      2
 6:  2   dg     76      7
 7:  3    g      5      5
 8:  3    g      5      5
 9:  5   gg     56      4
10:  6    g    456      3
11: 8v    g      6      6
12:  9    e 778795      2

这就像使用映射 table 创建新列,但使用连接代替。