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

R语言:如何仅将死亡年份对应的身高体重值设为NA?

问题与解决方案

问题背景

数据集

my_data = data.frame(id = c(1,2,3), status_2017 = c("alive", "alive", "alive"), status_2018 = c("alive", "dead", "alive"), status_2019 = c("alive", "dead", "dead"), height_2017 = rnorm(3,3,3), height_2018 = rnorm(3,3,3), 
                     height_2019 = rnorm(3,3,3) , weight_2017  = rnorm(3,3,3), weight_2018 = rnorm(3,3,3), weight_2019 = rnorm(3,3,3))

示例输出:

id status_2017 status_2018 status_2019 height_2017 height_2018 height_2019 weight_2017 weight_2018 weight_2019
1  1       alive       alive       alive    6.505447    7.328302  4.14945261   2.4715195    7.140026    1.843526
2  2       alive        dead        dead   -2.033761    3.553849  0.09896499   0.4159123    4.340485    1.366350
3  3       alive       alive        dead    3.107110    2.967456  6.52980219   1.6573734    3.397389    3.116294

需求

若某ID在某年份状态为dead,则将该年份对应的height和weight值替换为NA。

尝试的错误方法

dead_rows <- my_data$status_2018 == "dead" | my_data$status_2019 == "dead"

my_data[dead_rows, c("height_2018", "height_2019", "weight_2018", "weight_2019")] <- NA

问题:ID=3在2018年状态为alive,但该年份的身高体重却被设为NA,不符合需求。需要修正该问题,同时希望有无需手动列所有列名的简洁实现方式。


解决方案

一、修正原始索引方法

问题核心是错误地将整行标记为dead后批量替换所有年份列,正确做法是按年份单独匹配:只有对应年份的status为dead时,才替换该年份的指标列。

# 处理2018年:status_2018为dead的行,替换height_2018和weight_2018为NA
my_data[my_data$status_2018 == "dead", c("height_2018", "weight_2018")] <- NA

# 处理2019年:status_2019为dead的行,替换height_2019和weight_2019为NA
my_data[my_data$status_2019 == "dead", c("height_2019", "weight_2019")] <- NA

此方法精准匹配年份,ID=3的2018年数据会保留,仅2019年指标被设为NA。

二、Base R批量实现(无需手动列名)

针对年份较多的场景,可通过提取列名中的年份后缀自动匹配列:

# 提取所有年份后缀(从带年份的列名中解析)
years <- unique(sub(".*_(\\d{4})", "\\1", colnames(my_data)[grepl("_\\d{4}", colnames(my_data))]))

# 遍历每个年份,自动匹配status列和对应指标列
for (year in years) {
  status_col <- paste0("status_", year)
  metric_cols <- paste0(c("height_", "weight_"), year)
  
  my_data[my_data[[status_col]] == "dead", metric_cols] <- NA
}

此方法无需手动输入列名,可自动适配新增的年份列。

三、tidyverse简洁实现

通过长格式转换,逻辑更直观,适合复杂数据处理:

library(tidyverse)

my_data_clean <- my_data %>%
  # 转为长格式:将年份作为单独列,指标类型(status/height/weight)保留为列名
  pivot_longer(cols = -id, names_to = c(".value", "year"), names_sep = "_") %>%
  # 当status为dead时,将height和weight设为NA
  mutate(across(c(height, weight), ~ifelse(status == "dead", NA, .))) %>%
  # 转回宽格式,恢复原数据结构
  pivot_wider(names_from = year, values_from = c(status, height, weight))

处理后的数据严格按年份匹配status,自动完成NA替换,无需手动指定列名。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 06:24:35