我有一个.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
$ RgTime - 10分钟AS RadTimeNew
相关的dBZ到RadTimeNew AS dBZ.New。
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,....)来处理这个问题。
答案 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
添加到其参数中,然后删除最后一个元素。我用它来简单地追加你的两列的移位版本。但正如你所说,可能存在差距,我们必须找到这些差距。因此,我将RadTime
和Rgtime
列都转换为秒,并检查它们是否相差10分钟。对于那些不是这种情况的行,我将RadTimeNew
和dBZ.New
设置为NA
。如果我曾尝试编写hmsstr2secs(data$RadTimeNew)
而不是mylag(hmsstr2secs(data$RadTime))
,那么由于hmsstr2secs
未设计为在其输入中处理NA
,因此会失败。
这个版本可能比上面那个版本更快,因为它不必像每个其他行那样比较每一行,就像merge
那样,但是可以利用这个事实,如果有的话完全匹配,它在连续的行之间。它还避免了从秒到h:mm:ss字符串的转换,这意味着如果您的日期格式不同,就前导零等而言,它会更强大。
结果的一个不同之处在于,如果我们没有匹配,此版本的NA
列中会有RadTimeNew
,而上述版本的计算时间为没有匹配。