尝试替换for循环时出现索引和ifelse语句问题

时间:2019-06-29 15:53:39

标签: arrays r dataframe if-statement na

我想替换下面的for循环,因为必须有一种更简单的方法,如果数据帧很大,for循环会花费很多时间来计算。

示例数据帧df由几列组成。每列的长度为1,000个条目。列ID包含字母数字标识符,而所有其他列包含数字NA

ID <- c(rep("ID1", 400), rep("ID2", 400), rep("ID3", 200))

set.seed(264060397)

A <- round((runif(1000, 1.0, 1000.0)), digits = 2)
A[sort(sample(c(1:1000), 50, replace = TRUE))] <- NA
B <- round((runif(1000, 1.0, 1000.0)), digits = 2)
B[sort(sample(c(1:1000), 35, replace = TRUE))] <- NA
C <- round((runif(1000, 1.0, 1000.0)), digits = 2)
C[sort(sample(c(1:1000), 243, replace = TRUE))] <- NA

df <- data.table(ID, A, B, C)

我现在想添加一个名为D的新列,其中应包含计算值。 for循环完成了应做的工作,但是如果数据帧很大,则需要花费一些时间才能完成。但是,1,000应该不是计算问题。另一方面,15,000可能会导致非常繁忙的for循环。

df[, D := NA]
df$D = as.numeric(as.character(df$D))
df <- as.data.frame(df)

for(i in 2:length(df$ID)) {
  if(df$ID[i] == df$ID[i - 1]) {
    if(is.na(df$C[i])) {
      df$D[i] <-
        df$A[i] - df$A[i - 1] -
        df$B[i] - df$B[i - 1]
    } else {
      df$D[i] <-
        df$A[i] - df$A[i - 1]   
    }
  }
}

View(df)显示D的某些值是NA,但这无关紧要。

接下来,我尝试通过完全避免for循环来加快计算速度。但是,这不起作用。

df$D <- NULL

i = c(1:length(df$ID))
df[, D := ifelse(i == 1 || !(df$ID[i] == df$ID[i - 1]), NA,
                 ifelse(is.na(df$C[i]),
                        df$A[i] - df$A[i - 1] -
                        df$B[i] - df$B[i - 1],
                        df$A[i] - df$A[i - 1]
                 ))]

在此示例中,R引发以下错误消息:

Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").

如果我没有通过写入dfdf <- as.data.frame(df)从数据表转换为数据帧,R不会抛出错误消息。但是,列D仅包含NA。这些不是for循环计算的预期结果。 (请注意,我的真实代码针对的是数据帧。因此,该解决方案应该适用于数据帧。)

0 个答案:

没有答案