R语言遍历dataframe应用平滑函数循环报错如何解决?
错误原因
- 循环遍历范围语法错误:
1: inv.temp写法错误,inv.temp是365行73列的data.frame对象,不是数值。你需要遍历所有73列,应该用1:ncol(inv.temp)指定遍历1到列数的整数序列。你之前的写法相当于让R拿数据框当序列上限,自然会报NA/NaN的错误,同时警告你表达式有73个元素仅用了第一个。 - 存储结果的
ovi5没有预先初始化:单跑第10列时ovi5是365行1列的向量,循环需要存储73列的结果,必须先创建一个365行73列的空矩阵/数据框预留存储位置,不然直接对ovi5[,i]赋值会找不到对应列位。
修正后的完整代码
library(fda) library(fda.usc) data(aemet,package = "fda.usc") tt = aemet$temp$argvals temp = as.data.frame(aemet$temp$data,row.names=F) range.tt = aemet$temp$rangeval inv.temp = data.frame(t(aemet$temp$data)) # 365 x 73 matrix names(inv.temp) = aemet$df$name # 预先初始化存储结果的矩阵,365行对应时间点,73列对应所有站点 ovi5 <- matrix(NA, nrow = length(tt), ncol = ncol(inv.temp)) # 给结果矩阵加列名,对应站点名方便后续调用 colnames(ovi5) <- names(inv.temp) # 修正循环范围 for(i in 1:ncol(inv.temp)){ ovibasis5 = create.fourier.basis(rangeval = range(tt),nbasis = 5) ovifourier5.fd = smooth.basis(argvals = tt, y = inv.temp[,i],fdParobj = ovibasis5)$fd ovi5[,i] = eval.fd(tt,ovifourier5.fd) } ovi5
可选优化点
ovibasis5的创建不依赖列索引i,完全可以放到循环外执行,减少重复计算,提升运行效率:
# 提前创建公共的傅里叶基,不用循环内重复生成 ovibasis5 = create.fourier.basis(rangeval = range(tt),nbasis = 5) for(i in 1:ncol(inv.temp)){ ovifourier5.fd = smooth.basis(argvals = tt, y = inv.temp[,i],fdParobj = ovibasis5)$fd ovi5[,i] = eval.fd(tt,ovifourier5.fd) }
内容的提问来源于stack exchange,提问作者Ishman
相关产品推荐
相关产品推荐

