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

R语言中高效标记首次出现模式的所有年份行的方法

问题与解决方案

问题描述

现有如下R数据集:

year = c("2000", "2000", "2000", "2002", "2000", "2002", "2007")
id = c("X", "X", "X", "X", "Z", "Z", "Z")
product = c("apple", "orange", "orange", "orange", "cake", "cake", "bacon")
market = c("CHN", "USA", "USA", "USA", "SPA", "CHL", "CHL")
df = data.frame(year, id, product, market)

需要创建三个变量:

  • FPFM:若当前行是id-产品-市场组合首次出现的年份,取值为1;否则为0
  • FP:若当前行是id-产品组合首次出现的年份,取值为1;否则为0
  • FM:若当前行是id-市场组合首次出现的年份,取值为1;否则为0

期望输出数据集:

year = c("2000", "2000", "2000", "2002", "2000", "2002", "2007")
id = c("X", "X", "X", "X", "Z", "Z", "Z")
product = c("apple", "orange", "orange", "orange", "cake", "cake", "bacon")
market = c("CHN", "USA", "USA", "USA", "SPA", "CHL", "CHL")
FPFM = c(1, 1, 1, 0, 1, 1, 1)
FP = c(1, 1, 1, 0, 1, 0, 1)
FM = c(1, 1, 1, 0, 1, 1, 0)
df_desired = data.frame(year, id, product, market, FPFM, FP, FM)

用户尝试的代码仅标记每组的第一行,无法将同一首次年份的所有行标记为1,且希望避免多次汇总后连接的低效方法:

df_new <- df %>%
  arrange(id, year) %>% 
  group_by(id, product, market) %>% 
  mutate(FPFM = row_number(year) == 1) %>% 
  as.data.frame() %>% 
  group_by(id, product) %>% 
  mutate(FP = row_number(year) == 1) %>% 
  as.data.frame() %>% 
  group_by(id, market) %>% 
  mutate(FM = row_number(year) == 1) %>% 
  as.data.frame() 

高效解决方案

核心思路是:针对每个分组,找到该组首次出现的年份(即分组内最小的年份),判断当前行的年份是否等于这个最小年份,将结果转为1/0即可。全程在dplyr管道内完成,无需拆分或连接数据:

library(dplyr)

df_result <- df %>%
  # 先将year转为数值型,确保年份比较准确(原字符型也可比较,转数值更稳妥)
  mutate(year = as.numeric(year)) %>%
  # 按id-产品-市场分组,标记首次出现年份的所有行
  group_by(id, product, market) %>%
  mutate(FPFM = as.integer(year == min(year))) %>%
  # 按id-产品分组,标记首次出现年份的所有行
  group_by(id, product) %>%
  mutate(FP = as.integer(year == min(year))) %>%
  # 按id-市场分组,标记首次出现年份的所有行
  group_by(id, market) %>%
  mutate(FM = as.integer(year == min(year))) %>%
  # 取消分组,恢复为普通数据框
  ungroup() %>%
  # 把year转回字符型(如果需要和原数据格式一致)
  mutate(year = as.character(year))

代码说明

  1. year == min(year):判断当前行的年份是否是该分组的最小年份(即首次出现的年份),返回布尔值TRUE/FALSE
  2. as.integer():将布尔值转为1/0,符合需求的数值格式
  3. 全程使用管道操作,无需拆分或连接数据,处理大数据集时效率更高

验证结果:输出的df_result与期望的df_desired完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:55:17