在 R 中计算 'if statement' 中的空值的问题
Problem with counting null values in 'if statement' in R
我将一些数据传递给 R 中的一个简单代码块,该代码块计算空值,然后执行 ARIMA 时间序列插补。我写了一个非常简单的 'if' 语句来计算时间序列中的空值,如果它们小于一定数量,则忽略该列并移至下一列(因为 ARIMA 插补需要一定的非空数据的数量才能工作,否则它 returns 一个错误)。计算空值似乎工作正常,但 if 语句的行为非常奇怪并且不起作用。我包含了一个 print 语句来计算 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个null,和时间序列的长度一样。因此 if 语句不应该 运行 在 'if' 语句中再次计算空值数量的行,因为应该绕过这行代码。 IE。对于与列 pm10_iqr 相关的时间序列,空值的数量为 17520,时间序列的长度为 17520,这将导致 arima 失败 - 因此 if 语句应跳过此行。但它不会这样做。
请问我哪里错了?这应该很简单但是没有任何意义!我不写很多 R 代码,通常 Python。感谢您的帮助!
sum(is.na(ts) != length(ts))
应该是
sum(is.na(ts)) != length(ts))
解释出了什么问题:在 R 中,除 0 以外的任何数字都计算为 TRUE。例如:
if (0) {print("evaluated to TRUE")} else {print("evaluated to FALSE")} and
Returns:
[1] "evaluated to FALSE"
和:
if (5) {print("evaluated to TRUE")} else {print("evaluated to FALSE")}
Returns:
[1] "evaluated to TRUE"
另外,R 接受布尔值(TRUE
、FALSE
)作为sum
(和其他算术函数)的参数并对待它们在这些情况下为 1 (TRUE
) 和 0 (FALSE
).
is.na(ts) != length(ts)
求值为 TRUE 和 FALSE 的向量
和
sum(is.na(ts) != length(ts))
愉快地总结它们 ;)
这就是为什么您的代码没有引发任何错误,因为它有点在工作,只是没有按照我们的意思去做...这些是我最害怕的错误 ;)
我将一些数据传递给 R 中的一个简单代码块,该代码块计算空值,然后执行 ARIMA 时间序列插补。我写了一个非常简单的 'if' 语句来计算时间序列中的空值,如果它们小于一定数量,则忽略该列并移至下一列(因为 ARIMA 插补需要一定的非空数据的数量才能工作,否则它 returns 一个错误)。计算空值似乎工作正常,但 if 语句的行为非常奇怪并且不起作用。我包含了一个 print 语句来计算 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个null,和时间序列的长度一样。因此 if 语句不应该 运行 在 'if' 语句中再次计算空值数量的行,因为应该绕过这行代码。 IE。对于与列 pm10_iqr 相关的时间序列,空值的数量为 17520,时间序列的长度为 17520,这将导致 arima 失败 - 因此 if 语句应跳过此行。但它不会这样做。
请问我哪里错了?这应该很简单但是没有任何意义!我不写很多 R 代码,通常 Python。感谢您的帮助!
sum(is.na(ts) != length(ts))
应该是
sum(is.na(ts)) != length(ts))
解释出了什么问题:在 R 中,除 0 以外的任何数字都计算为 TRUE。例如:
if (0) {print("evaluated to TRUE")} else {print("evaluated to FALSE")} and
Returns:
[1] "evaluated to FALSE"
和:
if (5) {print("evaluated to TRUE")} else {print("evaluated to FALSE")}
Returns:
[1] "evaluated to TRUE"
另外,R 接受布尔值(TRUE
、FALSE
)作为sum
(和其他算术函数)的参数并对待它们在这些情况下为 1 (TRUE
) 和 0 (FALSE
).
is.na(ts) != length(ts)
求值为 TRUE 和 FALSE 的向量
和
sum(is.na(ts) != length(ts))
愉快地总结它们 ;)
这就是为什么您的代码没有引发任何错误,因为它有点在工作,只是没有按照我们的意思去做...这些是我最害怕的错误 ;)