You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

在R中如何基于相邻行的x变量值生成判断变量z?

解决相邻行x值差异生成z列的问题

我来帮你搞定这个需求!你想要生成的z列逻辑很清晰:第一行设为NA,之后每行如果和前一行的x值不同就取1,相同则取0。你的循环写法出了几个小问题,我先帮你修正循环,再给你推荐更高效的矢量化方法~

先看你的循环问题出在哪

你的两个循环都有关键错误:

  • 你用了length(df),这个返回的是数据框的列数(这里是3),而不是行数!应该用nrow(df)或者length(df$x)来获取行数。
  • 第一个循环里,每次都给整个df$z赋值,最后只会保留最后一次循环的结果,而不是逐行更新。
  • 第二个循环里用了df$z == 1(这是判断操作,不是赋值),正确的赋值应该是df$z[i] <- 1

修正后的循环写法

先初始化z列为NA,然后从第2行开始逐行判断赋值:

df <- data.frame( 
  x = c(1, 1, 2, 0, 0, 0, 0, 1, 1, 2), 
  y = c(1, 1, 2, 0, 0, 0, 0, 1, 1, 2), 
  z = c(0, 1, 2, 0, 0, 0, 0, 1, 1, 2) 
)

# 初始化z列,第一行为NA
df$z <- NA
# 从第2行到最后一行循环
for (i in 2:nrow(df)) {
  df$z[i] <- ifelse(df$x[i] != df$x[i-1], 1, 0)
}

# 查看结果
df

运行后就能得到你想要的z列啦。

更高效的矢量化方法(推荐)

在R里,矢量化操作比循环更快更简洁,不用写循环就能搞定:

Base R 方法

diff()函数计算相邻x的差值,再判断是否不等于0,最后把结果转成整数,前面加NA作为第一行:

df$z <- c(NA, as.integer(diff(df$x) != 0))

dplyr 方法(适合tidyverse用户)

lag()函数获取前一行的x值,再用case_when()做条件判断:

library(dplyr)

df <- df %>%
  mutate(z = case_when(
    row_number() == 1 ~ NA_integer_,  # 第一行设为NA
    x != lag(x) ~ 1L,                 # 和前一行x不同取1
    TRUE ~ 0L                         # 否则取0
  ))

这两种方法都能直接得到你期望的结果,和你给出的df_expected完全一致。

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

火山引擎 最新活动