R语言求助:如何在数据集分组内首次出现0时设新变量为1
解决分组内首次出现0的标记问题
我来帮你搞定这个需求!看起来你需要在每个ID分组内,标记出Var1和Var2各自第一次出现0的行(只要其中一个变量首次出现0,该行的VarNew就设为1),其余所有情况VarNew都设为0。下面给你两种常用的实现方案,都是R语言里的主流工具链:
方法一:用dplyr(tidyverse风格)
这是最直观易懂的方式,适合习惯tidyverse语法的用户:
首先加载必要的包:
library(tidyverse)
然后对数据集进行分组处理:
# 假设你的原始数据集名为df df <- df %>% group_by(ID) %>% # 按ID分组 mutate( # 标记Var1首次出现0的行:累计0的次数为1且当前行是0 first_var1_zero = ifelse(cumsum(Var1 == 0) == 1 & Var1 == 0, 1, 0), # 同理标记Var2首次出现0的行 first_var2_zero = ifelse(cumsum(Var2 == 0) == 1 & Var2 == 0, 1, 0), # 只要任意一个变量首次出现0,VarNew就为1 VarNew = ifelse(first_var1_zero == 1 | first_var2_zero == 1, 1, 0) ) %>% select(-first_var1_zero, -first_var2_zero) %>% # 移除中间变量(可选) ungroup() # 取消分组
方法二:用data.table(高效大数据处理)
如果你的数据集非常大,data.table的处理速度会更快:
library(data.table) setDT(df) # 将数据框转换为data.table格式 df[, `:=`( first_var1_zero = as.integer(cumsum(Var1 == 0) == 1 & Var1 == 0), first_var2_zero = as.integer(cumsum(Var2 == 0) == 1 & Var2 == 0) ), by = ID][, VarNew := as.integer(first_var1_zero | first_var2_zero)][, c("first_var1_zero", "first_var2_zero") := NULL]
验证示例数据
用你给出的测试数据验证一下,结果完全符合预期:
# 测试数据 test_df <- tibble( ID = c(1,1,1,1,1,2,2,2,2,2), Var1 = c(1,1,0,0,0,1,1,1,0,0), Var2 = c(1,1,1,1,0,1,1,1,1,1) ) # 用方法一处理后输出 test_df %>% group_by(ID) %>% mutate( first_var1_zero = ifelse(cumsum(Var1 == 0) == 1 & Var1 == 0, 1, 0), first_var2_zero = ifelse(cumsum(Var2 == 0) == 1 & Var2 == 0, 1, 0), VarNew = ifelse(first_var1_zero == 1 | first_var2_zero == 1, 1, 0) ) %>% select(-first_var1_zero, -first_var2_zero) %>% ungroup()
输出结果:
# A tibble: 10 × 4 ID Var1 Var2 VarNew <dbl> <dbl> <dbl> <dbl> 1 1 1 1 0 2 1 1 1 0 3 1 0 1 1 4 1 0 1 0 5 1 0 0 1 6 2 1 1 0 7 2 1 1 0 8 2 1 1 0 9 2 0 1 1 10 2 0 1 0
为什么之前的ifelse没成功?
单独用ifelse()只能做逐行的条件判断,没办法跟踪分组内之前是否出现过0的状态。而我们用cumsum()来累计每个分组内变量等于0的次数,就能精准定位到第一次出现0的行啦!
内容的提问来源于stack exchange,提问作者philipp.kn_98
相关产品推荐
相关产品推荐

