【问题标题】:Assign an individual in a dataset to a particular state based on predetermined proportions in R根据 R 中的预定比例将数据集中的个体分配到特定状态
【发布时间】:2019-05-30 01:59:25
【问题描述】:

我有这样的数据

df <- data.frame(
age_grp10 = rep(c("00-09", "10-19", "20-29", "30-39", "40-49", "50-59", "60-    69", "70-79", "80-89"), 2),
sex = c(rep("M", 9), rep("F", 9)),
prob_arr = round((runif(18, min = 0.11, max = 2.50)), digits = 2),
prob_dep = round((runif(18, min = 0.11, max = 2.50)), digits = 2)
)

该数据集按年龄和性别提供了在一个日历年内到达或离开的人口比例。

然后我有人口水平的数据,看起来像这样

  pop_df <- data.frame(
  uniq_ID = c("AFG1234", "WED1234", "POJ1234", "DER234", "QWE1234", "BGR1234", "ABC1234", "DSE1234", "UHJ1234", "POI234",
          "EDC1234", "BGT1234", "MJI1234", "WEX1234", "FGH1234", "UJN1234", "LOK1234", "DRT1234", "URD1234", "MVR1234"),
  age_grp10 = c("50-59", "40-49", "20-29", "40-49", "00-09",  "50-59", "30-39", "70-79",  "60-69", "40-49",
            "80-89", "10-19", "30-39", "30-39", "50-59", "70-79", "00-09", "70-79", "20-29", "20-29"),
  sex = c("M", "M", "F", "M", "F", "F", "F", "M", "F", "M", "F", "F", "M", "M", "M", "M", "M", "F", "M", "F"))

在这个人口数据集中,每一行都是一个个体,大约有 500 万人。它显示了他们的年龄和性别,以及唯一的 ID 号。 根据第一个数据框(df)中的比例,我想将到达和离开状态分配给人口数据框(pop_df)中的个人。

我想要的输出看起来像

pop_df <- pop_df %>%
left_join(df) %>%
mutate(Arrived = c(0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0),
     Departed = c(1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))

在最后一个数据集中,Arrived 和 Departed 的值取决于 df 数据帧中的比例。因此,根据 df 数据帧中 prob_arr 的值,XX% 的 0-9 岁男性将被分配到达状态。

感谢您的帮助

【问题讨论】:

  • 大多数“概率”都大于 1——它们是百分比吗?
  • 另外,到达和离开是独立的吗?也就是说,将一个人标记为既到达又离开是否有意义?
  • 对不起,是的,它们实际上是比例。第三种选择既不到达也不离开。他们是独立的,尽管很少有人在同一年到达和离开。

标签: r random dplyr


【解决方案1】:

假设(a)概率是百分比,并且(b)它们是独立的,这是dplyr中的一个简单方法:

library(dplyr)
pop_df %>% left_join(df) %>%
  mutate(Arrived = as.integer(runif(n()) * 100 < prob_arr),
         Departed = as.integer(runif(n()) * 100 < prob_dep))

虽然在base 中同样的逻辑很简单:

joined_df = merge(pop_df, df)
transform(
  joined_df,
  Arrived = as.integer(runif(nrow(joined_df)) * 100 < prob_arr),
  Departed = as.integer(runif(nrow(joined_df)) * 100 < prob_dep)
)

【讨论】:

  • 谢谢格雷戈尔。 Arrivals 和 Departures 不是独立的,所以我将其稍微编辑为:pop_df %&gt;% left_join(df) %&gt;% mutate(Arrived = as.integer(runif(n()) * 100 &lt; prob_arr)) %&gt;% mutate(Departed = case_when(Arrived == 0 ~ as.integer(runif(n())*100 &lt; prob_dep), TRUE ~ 0))
  • 当你只有一个案例时不需要case_when,我会做mutate(Arrived = as.integer(runif(n()) * 100 &lt; prob_arr)), Departed = as.integer(runif(nrow(joined_df)) * 100 &lt; prob_dep &amp; !Arrived))。但这会低估离开人数,因为这会使离开人数占未到达者的百分比,而不是总人口的百分比。让我知道这是否相关,我可以通过更好的修复进行编辑。
  • 另一方面,您对问题的评论说“同一年到达和离开的人是不寻常的”,因此您可能希望将其保留为-是。如果你的概率约为 1%,那么有人到达和离开的概率大约是 1% * 1% = 0.01%,这确实很不寻常。如果你按照上面的 cmets 进行修复,它将是 0%。
  • 感谢您的帮助@Gregor。我想我可能解释错了,因为当我运行这段代码时,我没有得到我期望的移民数量。对于年龄和性别的每种组合,我都有一定数量的人在一年内离开或到达。我希望在运行您提供的代码后,预计到达或离开的人数将等于观察到的总人数。但事实并非如此。
  • 我不明白这条评论。让我们更具体一点。 df 的第一行显示年龄范围为 0-9 的男性,并给出 1.45 的 prob_arr。现在,作为严格的概率,这没有任何意义,因为概率和比例必须在 0 和 1 之间。所以,我假设这是一个*百分比,即 1.45% = 0.0145 比例(或概率)。所以,我的代码所做的是,给大 pop_df 中年龄组 0-9 中的每个男性一个 0.0145 的概率被标记为到达......
猜你喜欢
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 2017-10-28
  • 2019-05-06
  • 2021-09-08
相关资源
最近更新 更多