在 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 接受布尔值(TRUEFALSE)作为sum(和其他算术函数)的参数并对待它们在这些情况下为 1 (TRUE) 和 0 (FALSE).

is.na(ts) != length(ts)

求值为 TRUE 和 FALSE 的向量

sum(is.na(ts) != length(ts))

愉快地总结它们 ;)

这就是为什么您的代码没有引发任何错误,因为它有点在工作,只是没有按照我们的意思去做...这些是我最害怕的错误 ;)