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

如何基于变量x1及相邻x2生成指定规则的dummy变量?

问题描述

以下是用于演示的数据框生成代码:

d<-data.frame(x1=c(rep("no",5),rep("yes",4),rep("no",2),rep("yes",3),rep("no",2),rep("yes",3)),
              x2=c(rep("no",6),rep("yes",1),rep("no",9),rep("yes",2),rep("no",1)),
              dummy=c(rep(0,5),rep(1,4),rep(0,5),rep(0,2),rep(1,3)))

我拥有两个变量x1和x2,希望基于这两个指示变量生成一个名为'dummy'的dummy变量。具体规则为:当x1取值为"yes",且其所在的连续x1="yes"集群中至少有一个x2取值为"yes"时,dummy取值为1;若x1取值为"yes"但所在集群的x2均为"no",则dummy取值为0。

使用以下代码可以生成x1和x2同时为"yes"时取值为1的dummy变量:

d$dummy=ifelse(d$x1=="yes" & d$x2=="yes",1,0)

但该方法无法捕捉到连续的x1="yes"集群,而这正是我需要实现的效果。

我期望的输出示例如下:
输出示例图

请问该如何实现这一需求?

解决方案

可以通过分组标记连续x1集群+检查集群内是否存在x2=yes的思路实现,以下提供两种高效方法:

方法一:使用dplyr简洁实现(推荐)

利用分组函数识别连续的x1="yes"块,再判断每个块内是否包含x2="yes",最后生成dummy变量:

library(dplyr)

# 生成演示数据
d <- data.frame(
  x1 = c(rep("no",5), rep("yes",4), rep("no",2), rep("yes",3), rep("no",2), rep("yes",3)),
  x2 = c(rep("no",6), rep("yes",1), rep("no",9), rep("yes",2), rep("no",1))
)

d <- d %>%
  # 给连续的x1集群分配唯一分组ID
  mutate(group_id = cumsum(x1 != lag(x1, default = ""))) %>%
  # 按分组检查是否存在x2=yes
  group_by(group_id) %>%
  mutate(has_x2_yes = any(x2 == "yes")) %>%
  # 按规则生成dummy
  mutate(dummy = ifelse(x1 == "yes" & has_x2_yes, 1, 0)) %>%
  ungroup() %>%
  select(-group_id, -has_x2_yes)

print(d)

方法二:基础R实现(无需额外包)

如果不想加载第三方包,可通过位置扩展和范围合并实现:

# 生成演示数据
d <- data.frame(
  x1 = c(rep("no",5), rep("yes",4), rep("no",2), rep("yes",3), rep("no",2), rep("yes",3)),
  x2 = c(rep("no",6), rep("yes",1), rep("no",9), rep("yes",2), rep("no",1))
)

# 标记所有x2=yes的位置
x2_yes_pos <- which(d$x2 == "yes")

# 找到每个x2=yes所在的x1集群范围
get_cluster_range <- function(pos) {
  left <- pos
  while(left > 1 && d$x1[left-1] == "yes") left <- left - 1
  right <- pos
  while(right < nrow(d) && d$x1[right+1] == "yes") right <- right + 1
  c(left, right)
}
cluster_ranges <- lapply(x2_yes_pos, get_cluster_range)

# 合并重叠的集群范围
if(length(cluster_ranges) > 0) {
  merged <- do.call(rbind, cluster_ranges)
  merged <- merged[order(merged[,1]),]
  current <- merged[1,]
  final_ranges <- list()
  for(i in 2:nrow(merged)) {
    if(merged[i,1] <= current[2] + 1) {
      current[2] <- max(current[2], merged[i,2])
    } else {
      final_ranges <- c(final_ranges, list(current))
      current <- merged[i,]
    }
  }
  final_ranges <- c(final_ranges, list(current))
}

# 生成dummy变量
d$dummy <- 0
for(rng in final_ranges) {
  d$dummy[rng[1]:rng[2]] <- 1
}
d$dummy <- ifelse(d$x1 == "yes", d$dummy, 0)

print(d)

两种方法都能精准匹配需求,将连续x1="yes"且集群内存在x2="yes"的行标记为1,其余x1="yes"行标记为0。

内容的提问来源于stack exchange,提问作者Rei

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:10:00