如何根据 R 中另一个数据框中的概率创建具有值的变量?

问题描述 投票:0回答:3

我创建了一个名为数据的表。该表包含一个非唯一 ID 字段。

data <- data.frame(ID = sample(c(1:5), 10, replace = T))

我有另一个名为概率的表,其中包含 ID 字段的匹配项、相应的比率和名称:

probabilities <- data.frame(ID = c(1,1,2,2,3,3,4,4,4,5), ratio = c(0.9, 0.1, 0.4, 0.6, 0.8, 0.2, 0.3, 0.3, 0.4, 1.0), name = c("A", "B", "A", "C", "F", "G", "B", "C", "G", "F"))

我正在尝试在数据表中创建一个名为 name 的新变量。这将根据比率列使用概率表中的名称变量填充。

比如数据表中任何ID为1的应该有90%的几率是A,10%的几率是B。ID为4的应该有30%的几率变成B,30%的几率变成B C 和 40% 的机会是 G,等等。

有谁知道这是如何实现的?

我尝试了以下但出现错误:

#load packages
library(dplyr)


#create new variable called name
data <- data %>% 
  mutate(name = sample(probabilities$name[ID=probabilities$ID],
                       size = n(),
                       prop = probabilities$ratio[ID=probabilities$ID],
                       replace = TRUE))

mutate()
中的错误: !计算
name = sample(...)
时出现问题。
sample()
错误导致: !未使用的参数 (prop = probabilities$ratio[name = probabilities$name])

r dataframe tidyverse probability
3个回答
0
投票

base R 解决方案,使用 sapply() 和 sample():

data$name <- sapply( data$ID, function(ID) sample(x = probabilities[probabilities$ID==ID,"name"],prob = probabilities[probabilities$ID==ID,"ratio"],size = 1))

0
投票

一种方法是

count()
你的ID,加入概率数据,然后使用
reframe()
按ID抽样:

library(dplyr)

set.seed(99)
data <- data.frame(ID = sample(c(1:5), 10, replace = T))

data %>%
  count(ID) %>%
  left_join(probabilities, by = "ID") %>%
  reframe(name = sample(name, first(n), prob = ratio, replace = TRUE), .by = ID)

   ID name
1   1    A
2   2    C
3   2    C
4   3    F
5   4    B
6   4    C
7   4    B
8   4    G
9   5    F
10  5    F

要保留所有vars,可以将数据匹配回原来的顺序,绑定结果:

set.seed(99)
data <- data.frame(ID = sample(c(1:5), 10, replace = T), other_var = 1:10)

data |> 
  count(ID) |> 
  left_join(probabilities, by = "ID") |> 
  reframe(name = sample(name, first(n), prob = ratio, replace = TRUE), .by = ID) %>%
  slice(pmatch(data$ID, ID)) %>%
  select(name) %>%
  bind_cols(data, .)

   ID other_var name
1   1         1    A
2   4         2    B
3   5         3    F
4   3         4    F
5   2         5    C
6   2         6    C
7   5         7    F
8   4         8    C
9   4         9    B
10  4        10    G

0
投票

使用

data.table
非相等连接:

library(data.table)
set.seed(969943335)

data <- data.frame(ID = sample(c(1:5), 10, replace = T))
probabilities <- data.frame(ID = c(1,1,2,2,3,3,4,4,4,5), ratio = c(0.9, 0.1, 0.4, 0.6, 0.8, 0.2, 0.3, 0.3, 0.4, 1.0), name = c("A", "B", "A", "C", "F", "G", "B", "C", "G", "F"))

setDT(probabilities)[,cr := cumsum(ratio), ID][setDT(data)[,r := runif(.N)], .(ID, name), on = .(ID, cr > r), mult = "first"]
#>     ID name
#>  1:  1    A
#>  2:  5    F
#>  3:  1    A
#>  4:  4    B
#>  5:  1    A
#>  6:  2    A
#>  7:  5    F
#>  8:  1    A
#>  9:  1    B
#> 10:  5    F
© www.soinside.com 2019 - 2024. All rights reserved.