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

如何用tidyverse正确透视表并修复NOAA的SOI、ONI数据读取错误

NOAA SOI/ONI数据集读取错位问题修复方案

问题根因

你当前的代码存在三个核心错误导致首条记录和官方标注不符:

  • 读取数据集时n_max参数设置过小,截断了前几年的有效数据,SOI直接跳过了1948-1950年的记录,导致首条数据从1951年开始
  • 用filter删除值为-99.99/-99.90的行,这类值是NOAA官方定义的缺测标记,直接删除会导致时间序列行顺序错位
  • R语言substr函数的字符串索引从1开始计数,你写的substr(year, 0, 4)属于不规范写法,部分场景下会出现年份解析错误
  • 冗余的手动重构数据框操作会导致列错位,进一步放大数据偏移问题

修复后的完整代码

SOI数据集处理代码

library(tidyverse)
library(fpp3)

SOI <- read_table("https://psl.noaa.gov/data/correlation/soi.data",
                  skip = 1, 
                  n_max = 80, # 放大读取范围覆盖所有已发布年份
                  col_names = FALSE,
                  na = "-99.99") %>% # 读取时直接将缺测标记转为NA,避免删除行
  set_names(c('year', month.abb)) %>%
  pivot_longer(-year, 
               names_to = 'month',
               values_to = 'SOI') %>%
  mutate(
    year = as.integer(substr(year, 1, 4)), # 修正字符串索引参数
    YearMonth = yearmonth(paste(year, month))
  ) %>%
  select(YearMonth, SOI) %>% # 直接选择需要的列,避免手动重构数据框出错
  as_tsibble(index = YearMonth)

# 验证首条记录
head(SOI, 1)

运行后首条输出将对应1948年1月,SOI值为NA(对应官方标注的-99.99缺测值)。

ONI数据集处理代码

ONI <- read_table("https://psl.noaa.gov/data/correlation/oni.data",
                  skip = 1, 
                  n_max = 80,
                  col_names = FALSE,
                  na = "-99.90") %>%
  set_names(c('year', month.abb)) %>%
  pivot_longer(-year, 
               names_to = 'month',
               values_to = 'ONI') %>%
  mutate(
    year = as.integer(substr(year, 1, 4)),
    YearMonth = yearmonth(paste(year, month))
  ) %>%
  select(YearMonth, ONI) %>%
  as_tsibble(index = YearMonth)

# 验证首条记录
head(ONI, 1)

运行后首条输出将对应1950年1月,ONI值为-1.53,和官方标注一致。

核心修正点说明

  • 取消filter删除缺测值的逻辑,改为读取时直接将缺测标记转为NA,保证时间序列的连续性
  • 放大n_max参数取值,避免截断早期年份数据
  • 删除冗余的手动数据框重构逻辑,用select直接筛选需要的列,避免列错位

内容的提问来源于stack exchange,提问作者Rodrigo H. Ozon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:39:03