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

如何按game分组标记DataFrame中possession值的行变更情况?

问题描述

我有如下结构的DataFrame:

gamepossession
A - BA
A - BA
A - BA
A - BB
A - BA
C - DD
C - DD
C - DC
C - DC
C - DD

生成该数据的R代码:

library(tidyverse)

df <- tibble(
  game = c("A - B", "A - B", "A - B", "A - B", "A - B", "C - D", "C - D", "C - D", "C - D", "C - D"),
  possession = c("A", "A", "A", "B", "A", "D", "D", "C", "C", "D")
)

我想要添加第三列transit,用来标记possession列的值是否发生变更。尝试了以下代码,但结合group_by使用时无法正常工作:

df %>% 
group_by(game) %>% 
mutate(transit = ifelse(df$possession != dplyr::lag(df$possession), "yes", "no"))

期望得到的输出如下:

gamepossessiontransit
A - BANA
A - BAno
A - BAno
A - BByes
A - BAyes
C - DDNA
C - DDno
C - DCyes
C - DCno
C - DDyes
解决方案

你的代码问题出在使用df$possession直接引用原数据框的列,而非利用group_by后的分组上下文。在分组操作中,应直接使用列名,不需要df$前缀,且lag()会自动在每个分组内计算前一行的值。

修正代码(匹配期望输出)

df %>% 
  group_by(game) %>% 
  mutate(transit = case_when(
    is.na(lag(possession)) ~ NA_character_,
    possession != lag(possession) ~ "yes",
    TRUE ~ "no"
  )) %>%
  ungroup() # 可选,取消分组状态

简化版代码

如果不需要显式处理NA,也可以用ifelse:

df %>% 
  group_by(game) %>% 
  mutate(transit = ifelse(possession != lag(possession), "yes", "no"))

关键说明

  • 移除df$前缀后,dplyr会在每个game分组的子数据框中处理列,确保lag()只在当前分组内取前一行值
  • case_when可以清晰地将每个分组的第一行设为NA,后续行根据与前一行的对比结果返回"yes"或"no",完全匹配你的期望输出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 12:15:16