You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中如何根据长度不同的另一数据框的值生成虚拟变量

解决方案

方法1:tidyverse实现(推荐,无需循环,效率更高)

首先构造示例数据,再通过左连接+逻辑判断直接生成虚拟变量:

library(dplyr)

# 构造示例Df1
Df1 <- data.frame(
  id = c(rep(1,5), rep(2,4)),
  year = c(2017:2021, 2018:2021),
  x1 = c(0.3, 0.5, 0.45, 0.5, 0.6, 0.2, 0.3, 0.4, 0.5)
)

# 构造示例Df2
Df2 <- data.frame(
  id = c(1,2),
  year = c(2019, 2020)
)

# 生成目标数据框Df3
Df3 <- Df1 %>%
  left_join(Df2, by = "id", suffix = c("", "_ref")) %>%
  mutate(dummy = as.integer(year >= year_ref)) %>%
  select(-year_ref)

对应你实际的数据集,直接替换列名即可:

# 假设你两个原始表分别为:
# df_all:存所有id+年份的观测,对应原描述里的Df1
# df_implement:存每个id对应的实施年份,对应原描述里的Df2
data_school <- df_all %>%
  left_join(df_implement, by = "id_escola", suffix = c("", "_ref")) %>%
  mutate(internet_fixa = as.integer(ano >= ano_ref)) %>%
  select(-ano_ref)

方法2:base R实现

# 匹配每个id对应的参考年份
Df1$year_ref <- Df2$year[match(Df1$id, Df2$id)]
# 生成虚拟变量
Df1$dummy <- as.integer(Df1$year >= Df1$year_ref)
# 移除辅助列得到Df3
Df3 <- Df1[, !names(Df1) %in% "year_ref"]

原有循环报错原因&修复方案

报错核心原因是:部分id对应的current_subset(非NA的internet_fixa行)为空,导致year_implementation长度为0,if判断时找不到比较对象就抛出长度为0的错误。
如果一定要用循环实现,可添加非空判断简化逻辑:

for (id in unique(data_school$id_escola)) {
  current_subset <- subset(data_school, id_escola == id & !is.na(internet_fixa))
  # 跳过没有参考年份的id
  if(nrow(current_subset) == 0) next
  # 提取唯一参考年份,避免多值冲突
  year_implementation <- unique(current_subset$ano)[1]
  # 批量替换当前id的所有行,无需内层循环
  idx <- data_school$id_escola == id
  data_school$internet_fixa[idx] <- as.integer(data_school$ano[idx] >= year_implementation)
}

内容的提问来源于stack exchange,提问作者José Eduardo Puentes Arteta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:18:01