R时间序列分析中Data Frame转换数据加载失败及代码报错问题
大宗商品MOM变化与通胀率相关性分析代码报错解决
问题概述
用户尝试读取CSV文件,分析大宗商品、柴油MOM变化与通胀率的关系,绘制图表并计算相关性,但运行代码时出现列名长度不匹配、对象找不到等错误,同时困惑转换Data Frame时数据无法正常加载。
报错原因拆解
列名长度不匹配:
报错'names'属性的长度[39]必须与向量长度[8]匹配,核心是转置后的数据框列数和你要设置的列名数量完全不匹配。原代码里names(data) <- c("Commodity", dates),但转置后的数据框列数是商品数量(8个),而c("Commodity", dates)的长度是1+38=39,完全对应不上——这是因为你搞反了转置后的行列逻辑,把商品和日期的对应关系弄混了。对象找不到(如Wheat):
因为列名设置错误,数据框里根本没有Wheat这些列,反而这些是行名,所以ggplot自然找不到对应的对象。数据读取与转置逻辑混乱:
原代码用skip=1跳过第一行,但实际第一行可能是表头,导致读取后列名彻底混乱;转置时没保留商品名称作为标识,反而把数值转置后搞混了行列的实际意义。
修正后的代码(常规CSV结构)
假设你的CSV结构是:第一列是日期,后续列是各个商品、Inflation、Diesel的MOM数值,表头为Date,Wheat,Soybean,...,Inflation,Diesel,修正代码如下:
# 加载所需库 library(readr) library(dplyr) library(ggplot2) # 读取数据:默认第一行是表头,无需skip data <- read_csv("commodities_inflation_data.csv") # 转换日期格式(如果CSV里日期是"Jan 2020"这类格式) data$Date <- as.Date(paste0("01 ", data$Date), format = "%d %b %Y") # 定义关注的商品列表 commodities_of_interest <- c("Wheat", "Soybean", "Corn", "Ground_Beef", "Bacon", "Eggs", "Chicken") # 循环绘制对比图 for (commodity in commodities_of_interest) { # 商品vs通胀率 p1 <- ggplot(data, aes(x = Date)) + geom_line(aes(y = .data[[commodity]], color = commodity)) + geom_line(aes(y = Inflation, color = "通胀率")) + labs(title = paste(commodity, "月度变化率 vs 通胀率"), y = "百分比变化", x = "日期") + scale_color_manual(values = c("blue", "red")) + theme_minimal() print(p1) # 商品vs柴油变化率 p2 <- ggplot(data, aes(x = Date)) + geom_line(aes(y = .data[[commodity]], color = commodity)) + geom_line(aes(y = Diesel, color = "柴油")) + labs(title = paste(commodity, "月度变化率 vs 柴油变化率"), y = "百分比变化", x = "日期") + scale_color_manual(values = c("blue", "green")) + theme_minimal() print(p2) } # 计算商品与通胀率的相关性(处理缺失值) correlation_with_inflation <- sapply(data[, commodities_of_interest], function(x) { cor(x, data$Inflation, use = "complete.obs") }) # 计算商品与通胀、柴油的两两相关性 correlation_matrix <- cor(data[, c(commodities_of_interest, "Inflation", "Diesel")], use = "complete.obs") correlation_with_inflation_and_diesel <- correlation_matrix[commodities_of_interest, c("Inflation", "Diesel")] # 输出结果 cat("商品与通胀率的相关性:\n") print(correlation_with_inflation) cat("\n商品与通胀率、柴油变化率的相关性:\n") print(correlation_with_inflation_and_diesel)
适配特殊CSV结构的修正代码
如果你的CSV是第一行是商品名称,第一列是日期(即原代码想处理的转置前结构),用以下代码:
# 加载库 library(readr) library(dplyr) library(ggplot2) library(tidyr) # 读取原始数据 data_raw <- read_csv("commodities_inflation_data.csv") # 转置并整理数据 data_transposed <- t(data_raw[-1]) # 排除日期列 colnames(data_transposed) <- data_raw[[1]] # 用日期作为列名 data <- as.data.frame(data_transposed, stringsAsFactors = FALSE) data$Commodity <- rownames(data_transposed) # 添加商品名称列 rownames(data) <- NULL # 转换为长格式(更适合ggplot绘图) data_long <- pivot_longer(data, cols = -Commodity, names_to = "Date", values_to = "MOM") data_long$Date <- as.Date(data_long$Date, format = "%b %Y") # 根据实际日期格式调整 data_long$MOM <- as.numeric(data_long$MOM) # 确保数值类型正确 # 提取通胀和柴油的单独数据 inflation_data <- data_long %>% filter(Commodity == "Inflation") diesel_data <- data_long %>% filter(Commodity == "Diesel") # 定义关注的商品 commodities_of_interest <- c("Wheat", "Soybean", "Corn", "Ground_Beef", "Bacon", "Eggs", "Chicken") # 绘制对比图 for (commodity in commodities_of_interest) { commodity_data <- data_long %>% filter(Commodity == commodity) # 商品vs通胀 p1 <- ggplot() + geom_line(data = commodity_data, aes(x = Date, y = MOM, color = commodity)) + geom_line(data = inflation_data, aes(x = Date, y = MOM, color = "通胀率")) + labs(title = paste(commodity, "月度变化率 vs 通胀率"), y = "百分比变化", x = "日期") + scale_color_manual(values = c("blue", "red")) + theme_minimal() print(p1) # 商品vs柴油 p2 <- ggplot() + geom_line(data = commodity_data, aes(x = Date, y = MOM, color = commodity)) + geom_line(data = diesel_data, aes(x = Date, y = MOM, color = "柴油")) + labs(title = paste(commodity, "月度变化率 vs 柴油变化率"), y = "百分比变化", x = "日期") + scale_color_manual(values = c("blue", "green")) + theme_minimal() print(p2) } # 转回宽格式计算相关性 data_wide <- pivot_wider(data_long, names_from = Commodity, values_from = MOM) correlation_with_inflation <- sapply(data_wide[, commodities_of_interest], function(x) { cor(x, data_wide$Inflation, use = "complete.obs") }) correlation_matrix <- cor(data_wide[, c(commodities_of_interest, "Inflation", "Diesel")], use = "complete.obs") correlation_with_inflation_and_diesel <- correlation_matrix[commodities_of_interest, c("Inflation", "Diesel")] # 输出结果 cat("商品与通胀率的相关性:\n") print(correlation_with_inflation) cat("\n商品与通胀率、柴油变化率的相关性:\n") print(correlation_with_inflation_and_diesel)
原代码转置后数据无法加载的原因
- 转置逻辑颠倒了行列对应关系:转置后的行是原数据的列,列是原数据的行,但你错误地把
Commodity设为第一列,实际转置后的行名才是商品名称。 - 列名赋值完全错误:用
c("Commodity", dates)设置列名,长度和转置后的数据框列数不匹配,导致列名设置失败,后续所有依赖列名的操作全出错。 - 转置后数据类型未转换:转置后的数据是字符型(原数据可能有混合类型),没有转为数值型,绘图和相关性计算自然无法进行。
内容的提问来源于stack exchange,提问作者Sjsaw0624
相关产品推荐
相关产品推荐

