【发布时间】:2020-03-10 13:43:21
【问题描述】:
我将一些数据传递给 R 中的一个简单代码块,该代码块计算空值,然后执行 ARIMA 时间序列插补。我写了一个非常简单的“if”语句,它计算时间序列中的空值,如果它们小于一定数量,则忽略该列并转到下一个(因为 ARIMA 插补需要一定数量的非空数据才能工作,否则返回错误)。计算空值似乎可以正常工作,但是 if 语句的行为非常奇怪并且不起作用。我包含了一个打印语句来计算 if 语句内部和外部的空值,但是当 if 语句未执行时,if 语句将代码传递给循环。这是代码和输出:
stations <- c('BX1', 'BX2', 'BG3') # each station has a different data file
pollutants <- c('nox','no2','pm10','pm25') # each station contains data on a number of pollutants
for (s in stations) {
print(paste('starting imputation for station ', s, sep=" "))
s_result <- read.csv(paste("/path/to/file", s, "_rescaled.csv", sep=""))
for (p in pollutants) {
ts = c()
pcol = paste0(p,"_iqr",sep="") # find the right column
ts = s_result[[pcol]] # get the time series from the column
print(pcol) # check which pollutant we're working on
print(length(ts)) # test the length of the time series
print(sum(is.na(ts))) # test the number of nulls in the time series
if (sum(is.na(ts) != length(ts))) { # if the time series is not completely null
print(sum(is.na(ts))) # check the length of the time series again for testing
usermodel <- arima(ts, order = c(10, 1, 0))$model # calculate the arima
p_result <- na_kalman(ts, model = usermodel, maxgap = 24) # calculate the arima
s_result <- cbind(s_result,p_result) # add the computed column to the dataframe
names(s_result)[names(s_result) == "p_result"] <- paste0(p,"_imputed",sep ="")
} else { # otherwise add a null column
p_result <- c(NA, length=length(ts))
s_result <- cbind(s_result,p_result) # enter a null column
names(s_result)[names(s_result) == "p_result"] <- paste0(p,"_imputed",sep ="")
}
}
filename = paste0("/path/to/file", s, "_imputed_test.csv", sep="")
write.csv(s_result, filename, row.names = TRUE)
print(paste('completed imputation for station ', s, sep=" "))
}
问题是,这个 if 语句无法正常工作,因为它正在将数据传递给 if 语句内的 arima 插补,即使空值的数量等于时间序列的长度也是如此。这是输出:
[1] "starting imputation for station BG1"
[1] "nox_iqr"
[1] 17520
[1] 4660
[1] 4660
[1] "no2_iqr"
[1] 17520
[1] 4664
[1] 4664
[1] "pm10_iqr"
[1] 17520
[1] 17520
[1] 17520
Error in arima(ts, order = c(10, 1, 0)) : 'x' must be numeric
显然有问题,对于 pm10 污染物,有 17520 个空值,与时间序列的长度相同。因此,if 语句不应在 'if' 语句中再次运行计算空值数量的行,因为应该绕过这行代码。 IE。对于与列 pm10_iqr 相关的时间序列,空值数为 17520,时间序列的长度为 17520,这将导致 arima 失败 - 因此 if 语句应跳过此行。但它不这样做。
请问我哪里出错了?这应该很简单,但没有任何意义!我不写很多 R 代码,通常是 Python。感谢您的帮助!
【问题讨论】:
-
sum(is.na(ts) != length(ts))应该是sum(is.na(ts)) != length(ts)-> 注意sum表达式的右括号!我们想比较is.na(ts)的sum ... -
@dario,对不起,我不明白。请问你能解释一下语法吗?我正在使用 R studio,如果我进行替换,我会收到语法错误。
-
@LucieCBurgess 在您的示例代码中,您编写
if (sum(is.na(ts) != length(ts))) {在 R 中的意思是:ifis.na(ts) != length(ts)的总和然后做一些事情。你可能想要说的是:ifis.na(ts)的总和和ts的长度不一样,那就做点什么吧。 -
@dario,我误读了你的答案(由于 ->) - 我以为你打算用 -> 替换大括号。谢谢,这似乎有效。呸,我以为我对这个完全发疯了!将标记为已回答。谢谢你
标签: r if-statement null arima