在R中添加列和算术与时间

时间:2015-03-03 05:20:43

标签: r math time-series

我有一个.csv格式的表格,有12K行,如下所示:

St.      date        Rgtime      RadTime       Rain      dBZ 
3613006 20130113     0:06:00      0:06:00       2      -10.625 
3613006 20130113     0:16:00      0:16:00       7      -11.75 
3613006 20130113     0:26:00      0:26:00       1      -10.5625 
3613006 20130113     0:36:00      0:36:00       9      -11.28125 
3613006 20130113     0:46:00      0:46:00       3      -10.34375 
3613006 20130113     0:56:00      0:56:00       8      -11.6875 
3613006 20130113     1:06:00      1:06:00       9      -16 
3613006 20130113     1:16:00      1:16:00       6      -25.3125 
3613006 20130113     1:26:00      1:26:00       1      -16.3125 
3613006 20130113     1:36:00      1:36:00       0      -20.71875
  1. $ RgTime - 10分钟AS RadTimeNew

  2. 相关的dBZ到RadTimeNew AS dBZ.New。

  3. dBZ.new应该在Radtime和dBZ中找到匹配变量。

    预期结果:

    St.      date        Rgtime     RadTime    Rain      dBZ        RadTimeNew    dBZ.New 
    3613006 20130113   0:06:00      0:06:00    2       -10.625           NA         NA 
    3613006 20130113   0:16:00      0:16:00    7       -11.75         0:06:00    -10.625 
    3613006 20130113   0:26:00      0:26:00    1       -10.5625       0:16:00    -11.75 
    3613006 20130113   0:36:00      0:36:00    9       -11.28125      0:26:00    -10.5625 
    3613006 20130113   0:46:00      0:46:00    3       -10.34375      0:36:00    -11.28125 
    3613006 20130113   0:56:00      0:56:00    8       -11.6875       0:46:00    -10.34375 
    3613006 20130113   1:06:00      1:06:00    9       -16            0:56:00    -11.6875 
    3613006 20130113   1:16:00      1:16:00    6       -25.3125       1:06:00    -16 
    3613006 20130113   1:26:00      1:26:00    1       -16.3125       1:16:00    -25.3125 
    3613006 20130113   1:36:00      1:36:00    0       -20.7187       1:26:00    -16.3125
    

    我尝试使用lag(),但我的数据时间没有继续,并且有一些错误。所以我正在寻找一个新的脚本(循环,if,....)来处理这个问题。

1 个答案:

答案 0 :(得分:1)

首先你需要减去那10分钟。我假设您的列表示已用时间,而不是一天中的时间。由于这可能超过24小时,我宁愿不通过像POSIXct这样的日期和时间数据类型,而是自己做数学,如下所示:

hms <- t(sapply(strsplit(as.character(data$Rgtime), ":"), as.integer))
secs <- (hms[,1]*60 + hms[,2])*60 + hms[,3] - 10*60
hms <- matrix(as.integer(c(secs %/% 3600, secs %/% 60 %% 60, secs %% 60)),
              ncol=3)
data$RadTimeNew <- sprintf("%d:%02d:%02d", hms[,1], hms[,2], hms[,3])
data$RadTimeNew[secs < 0] <- NA

然后你想找到匹配的值。合并可以为您做到这一点:

data <- merge(data, data.frame(RadTimeNew=data$RadTime, dBZ.New=data$dBZ),
              all.x=TRUE)

如果您愿意,可以重新排序结果列:

data <- data[c(2,3,4,5,6,7,1,8)]

作为替代方案,你可以这样做:

mylag <- function(v) v[c(NA,1:length(v)-1)]
data$RadTimeNew <- mylag(data$RadTime)
data$dBZ.New <- mylag(data$dBZ)
hmsstr2secs <- function(str) {
    hms <- sapply(strsplit(as.character(str), ":"), as.integer)
    return ((hms[1,]*60 + hms[2,])*60 + hms[3,])
}
nomatch <- (hmsstr2secs(data$Rgtime) - 600 != mylag(hmsstr2secs(data$RadTime)))
data$RadTimeNew[nomatch] <- NA
data$dBZ.New[nomatch] <- NA

函数mylag只是将NA添加到其参数中,然后删除最后一个元素。我用它来简单地追加你的两列的移位版本。但正如你所说,可能存在差距,我们必须找到这些差距。因此,我将RadTimeRgtime列都转换为秒,并检查它们是否相差10分钟。对于那些不是这种情况的行,我将RadTimeNewdBZ.New设置为NA。如果我曾尝试编写hmsstr2secs(data$RadTimeNew)而不是mylag(hmsstr2secs(data$RadTime)),那么由于hmsstr2secs未设计为在其输入中处理NA,因此会失败。

这个版本可能比上面那个版本更快,因为它不必像每个其他行那样比较每一行,就像merge那样,但是可以利用这个事实,如果有的话完全匹配,它在连续的行之间。它还避免了从秒到h:mm:ss字符串的转换,这意味着如果您的日期格式不同,就前导零等而言,它会更强大。

结果的一个不同之处在于,如果我们没有匹配,此版本的NA列中会有RadTimeNew,而上述版本的计算时间为没有匹配。