【问题标题】:Iterate over a column ignoring but retaining NA values in R遍历忽略但保留 R 中的 NA 值的列
【发布时间】:2018-08-28 16:38:59
【问题描述】:

我在 R 中有一个时间序列数据框,它有一列 V1,它由整数组成,其中散布着一些 NA。我想遍历此列并在之前的一个时间步中从自身中减去 V1。但是,我想忽略 V1 中的 NA 值并在减法中使用最后一个非 NA 值。如果 V1 的当前值为 NA,则差值应返回 NA。请参阅下面的示例

V1 <- c(1, 3, 4, NA, NA, 6, 9, NA, 10)
time <- 1:length(V1)
dat <- data.frame(time = time,
                     V1 = V1)
lag_diff <- c(NA, 2, 1, NA, NA, 2, 3, NA, 1) # The result I want
diff(dat$V1) # Not the result I want

我不希望使用循环来执行此操作,因为我有数百个数据帧,每个数据帧都超过 10,000 行。

解决这个问题的第一个想法是过滤掉 NA 行,执行迭代差异计算,然后重新插入被过滤掉的行,但我想不出办法。这样做似乎也不是很“整洁”,我不确定它是否会比循环更快。任何帮助表示赞赏,如果解决方案使用 tidyverse 函数,则加分。

【问题讨论】:

    标签: r iteration


    【解决方案1】:
    dat[!is.na(dat$V1), 'lag_diff'] <- c(NA, diff(dat[!is.na(dat$V1), 'V1']))
    #   time V1 lag_diff
    # 1    1  1       NA
    # 2    2  3        2
    # 3    3  4        1
    # 4    4 NA       NA
    # 5    5 NA       NA
    # 6    6  6        2
    # 7    7  9        3
    # 8    8 NA       NA
    # 9    9 10        1
    

    或者data.table(结果相同)

    library(data.table)
    setDT(dat)
    
    dat[!is.na(V1), lag_diff := V1 - shift(V1)]
    
    #    time V1 lag_diff
    # 1:    1  1       NA
    # 2:    2  3        2
    # 3:    3  4        1
    # 4:    4 NA       NA
    # 5:    5 NA       NA
    # 6:    6  6        2
    # 7:    7  9        3
    # 8:    8 NA       NA
    # 9:    9 10        1
    

    【讨论】:

    • 哇。我不敢相信它是如此简单。我当然不需要任何 tidyverse 函数,因为您可以使用基本索引来完成。
    【解决方案2】:

    tidyverse 版本,以防万一。不过它确实需要filter

    dat %>% 
      filter(!is.na(V1)) %>% 
      mutate(diff=V1- lag(V1)) %>% 
      right_join(dat,by=c("time","V1"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 2018-11-23
      • 1970-01-01
      相关资源
      最近更新 更多