R基于A列条件及新列自身上一行值生成新列B的实现问题
问题原因分析
- 报错原因:通常有两种可能:一是你没有提前加载dplyr包,导致mutate函数无法识别数据框对象;二是你的工作环境中存在名为
df的函数,覆盖了你创建的df数据框,可以先运行rm(df)清除变量后重新生成数据框测试。 - 逻辑错误原因:即使解决了报错,你用
mutate + lag的组合也无法得到正确结果。因为mutate是向量化运算,lag(B)取的是计算前B列的上一行值,而你的需求里B列每一行的取值都依赖上一行刚计算完成的动态B值,属于迭代依赖场景,普通向量化运算无法直接处理。
解决方案
方案1:使用purrr::accumulate(tidyverse生态方案)
accumulate是专门用于迭代累积计算的函数,刚好匹配你的需求,每一步计算都会把上一步的输出作为参数传入当前计算:
# 加载依赖包 library(dplyr) library(purrr) # 生成测试数据 A <- c(1,0,2,0,2,0,2,0,2,0,2,0,1,0,1,0,2,0,2,0,1,0,2,0) Bdesiredoutcome <- c(1,1,2,2,3,3,4,4,5,5,6,6,1,1,1,1,2,2,3,3,1,1,2,2) df <- data.frame(A, Bdesiredoutcome) # 计算B列 df <- df %>% mutate(B = accumulate(A, function(prev_b, current_A) { case_when( current_A == 1 ~ 1, current_A == 0 ~ prev_b, current_A == 2 ~ prev_b + 1 ) }))
运行后生成的B列和预期结果完全一致。
方案2:基础R循环方案
如果你不想加载额外包,用基础的for循环也可以实现,逻辑更直观:
# 生成测试数据 A <- c(1,0,2,0,2,0,2,0,2,0,2,0,1,0,1,0,2,0,2,0,1,0,2,0) Bdesiredoutcome <- c(1,1,2,2,3,3,4,4,5,5,6,6,1,1,1,1,2,2,3,3,1,1,2,2) df <- data.frame(A, Bdesiredoutcome) # 初始化B列 df$B <- NA_real_ df$B[1] <- 1 # 第一行A为1,直接赋值为1 # 从第二行开始迭代计算 for (i in 2:nrow(df)) { if (df$A[i] == 1) { df$B[i] <- 1 } else if (df$A[i] == 0) { df$B[i] <- df$B[i-1] } else if (df$A[i] == 2) { df$B[i] <- df$B[i-1] + 1 } }
内容的提问来源于stack exchange,提问作者Gebruiker10
相关产品推荐
相关产品推荐

