【问题标题】:How to create a dummy in dataframe according to value in another dataframe with a different length of observations in R?如何根据另一个数据帧中的值在 R 中创建一个具有不同观察长度的数据帧中的虚拟对象?
【发布时间】:2021-10-20 15:55:16
【问题描述】:

提前感谢您阅读我的问题。

在 R 中,我有以下两个数据框(Df1 和 Df2)——它们是我刚刚编写的示例——我打算根据以下规则创建一个虚拟变量:对于 Df1 中的每个 id,如果年份如果这个观测id大于或等于Df2中年份的观测id,则dummy取值为1,否则为0。数据框 Df3 是我希望达到的结果。我该怎么做? Df1

id year x1
1 2017 0.3
1 2018 0.5
1 2019 0.45
1 2020 0.5
1 2021 0.6
2 2018 0.2
2 2019 0.3
2 2020 0.4
2 2021 0.5

Df2

id year
1 2019
2 2020

Df3

id year x1 dummy
1 2017 0.3 0
1 2018 0.5 0
1 2019 0.45 1
1 2020 0.5 1
1 2021 0.6 1
2 2018 0.5 0
2 2019 0.45 0
2 2020 0.5 1
2 2021 0.6 1

一些上下文:

我尝试为我正在处理的真实数据框创建两个循环。下面是我尝试过的代码。数据框称为 data_school,我的 id、year 和虚拟变量分别是 id_escola、ano 和 internet_fixa。我在我的两个初始数据帧之间进行了完全连接,结果我得到了 data_school。由于它是多对一连接,因此我创建了虚拟变量,只有完全匹配的值等于 1,其他一切都是 NA。然后我开始执行以下循环,首先迭代所有 id 并获取每个 id,虚拟对象的参考年份,然后迭代该 id 的每个唯一年份并根据规则替换它。对于第一行,它运行良好,但在某些行之后,它会收到以下错误“if (data_school[data_school$id_escola == id & data_school$ano == : argument is of length zero”我该怎么办?

for (id in unique(data_school$id_escola)) {
  current_subset <- subset(data_school, id_escola == id & is.na(internet_fixa) == F)
  year_implementation <- current_subset$ano
  current <- subset(data_school, id_escola == id)
  for (i in unique(current$ano)){
    if (data_school[data_school$id_escola == id & data_school$ano == i,]$ano < year_implementation) {
      data_school[data_school$id_escola == id & data_school$ano == i, "internet_fixa"] <- 0
    } else {
      data_school[data_school$id_escola == id & data_school$ano == i, "internet_fixa"] <- 1
    }
  }
}

P.S.:如果你愿意,如果不够清楚,你可以忽略最后一部分(一些上下文)。

【问题讨论】:

  • 请使用 dput 创建一些 R 代码来重构您的示例,供我们用来设计答案。

标签: r dataframe dplyr


【解决方案1】:

这行得通吗:

library(dplyr)
df2 %>% rename('df2_year' = year) %>% left_join(df1, by = 'id') %>% group_by(id) %>% mutate(dummy = if_else(year >= df2_year, 1, 0)) %>% select(-df2_year)
# A tibble: 6 x 4
# Groups:   id [2]
     id  year    x1 dummy
  <int> <int> <dbl> <dbl>
1     1  2017  0.3      0
2     1  2018  0.5      0
3     1  2019  0.45     1
4     1  2020  0.5      1
5     1  2021  0.6      1
6     2    NA NA       NA

使用的数据:

df1
  id year   x1
1  1 2017 0.30
2  1 2018 0.50
3  1 2019 0.45
4  1 2020 0.50
5  1 2021 0.60
df2
  id year
1  1 2019
2  2 2020
  • 您的示例数据中的 df1 中缺少 id = 2。

【讨论】:

  • 谢谢,我已经用 df1 修复了表。它应该对 id 2 有一些观察。
  • @JoséEduardoPuentesArteta,我的代码仍然有效,请检查。
  • 再次感谢您!我进行了测试,它适用于我的代码。
【解决方案2】:

我们可以使用data.table 的连接

library(data.table)
setDT(df1)[df2, dummy := +(year >= i.year), on = .(id)]

-输出

> df1
   id year   x1 dummy
1:  1 2017 0.30     0
2:  1 2018 0.50     0
3:  1 2019 0.45     1
4:  1 2020 0.50     1
5:  1 2021 0.60     1

数据

df1 <- structure(list(id = c(1L, 1L, 1L, 1L, 1L), year = 2017:2021, 
    x1 = c(0.3, 0.5, 0.45, 0.5, 0.6)), class = "data.frame", row.names = c(NA, 
-5L))

df2 <- structure(list(id = 1:2, year = 2019:2020),
 class = "data.frame", row.names = c(NA, 
-2L))

【讨论】:

    猜你喜欢
    • 2018-01-09
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多