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

使用dplyr按年份计算总溶解固体占比的技术求助

解决dplyr计算年度TDS占比的问题

我来帮你梳理下代码里的关键问题,再给出修正后的方案,刚好能满足你要的19行2列年度占比数据集需求:

原代码的核心问题

  • 错误的提前过滤:你第一步就把val > 50的数据保留下来,这会丢失大量用来计算占比的基础样本(比如TDS在50-500之间的样本),占比必须基于当年所有TDS样本来计算,不能提前筛除。
  • 占比逻辑错误:当前prop的计算是用单个TDS数值除以当年总和,这是单值在总量中的占比,而你需要的是当年TDS>500的样本数占总样本数的比例。
  • 重复冗余的类型转换:每次都写as.numeric(as.character(val))既麻烦又容易出错,应该提前把val转成数值型。
  • 年份提取不够直观:用cut转成Date类型的年份不如直接提取数字年份方便后续输出。

修正后的完整代码

先确保加载必要的工具包(推荐用lubridate简化日期处理):

if (!require(pacman)) { install.packages('pacman') }
pacman::p_load("dplyr", "lubridate")

然后处理数据并计算占比:

# 读取原始数据(保持你的读取逻辑)
roadsalt_data <- read.table("QADportaldata_1988-2015.tsv", header=T, sep="\t", fill=T, stringsAsFactors = F)

# 预处理:转换日期、把val转为数值型、过滤目标数据
processed_data <- roadsalt_data %>%
  mutate(
    stdate = as.Date(stdate),
    val = as.numeric(val) # 提前转换,避免后续重复操作
  ) %>%
  # 精准筛选1997-2015年的TDS数据
  filter(
    charnam == "Total dissolved solids",
    year(stdate) %in% 1997:2015
  ) %>%
  select(orgid, stdate, locid, charnam, val) # 保留需要的列

# 计算年度TDS>500的占比
percent_data <- processed_data %>%
  mutate(year = year(stdate)) %>% # 提取数字年份
  group_by(year) %>%
  summarise(
    total_samples = n(), # 当年总样本数
    tds_over_500 = sum(val > 500, na.rm = TRUE), # 当年TDS>500的样本数(自动处理NA)
    pct_over_500 = round(tds_over_500 / total_samples * 100, 2) # 计算占比并保留两位小数
  ) %>%
  select(year, pct_over_500) # 只保留需要的两列

关键步骤说明

  1. 提前转换数值类型:把val转成数值型后,后续计算不用重复写类型转换代码,同时as.numeric()会自动把非数值的字符转为NA,后续用na.rm=TRUE忽略这些缺失值。
  2. 精准时间筛选:用year(stdate) %in% 1997:2015直接锁定你需要的19年,比日期范围更精准。
  3. 占比逻辑修正:用n()获取当年总样本数,sum(val>500)统计符合条件的样本数(逻辑值TRUE会被转为1,FALSE转为0),再计算比例。
  4. 最终结构调整:通过select()只保留年份和占比,完美得到你要的19行2列数据集。

如果原始数据里val有大量空值或非数值内容,可以在转换时加上na_if()优化:

val = as.numeric(na_if(val, "")) # 将空字符串转为NA

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:23:33