如何解决R:在不同长度且充满 NaN 的 data.frame 中自动偏移 - 确定 df 中每个单元格的最接近的非 NaN 值
我卡住了。我尝试了不同的方法,但没有运气。并且真的可以使用一些帮助:)
任务 我们有一个相当大的位移数据(斜率不稳定)data.frame (dd),它随着持续监测而增长。例如:
> dd[140:148,1:5]
UTC.Time Punkt.11 Punkt.13 Punkt.14 Punkt.21
138 2019-09-01 129.6067 110.1933 99.34375 208.1152
139 2019-09-02 NaN NaN NaN NaN
140 2019-09-03 133.7353 113.6303 102.26286 212.8912
141 2019-09-04 135.0769 114.7829 103.29231 215.2500
142 2019-09-05 136.2333 115.9917 103.80000 216.6250
143 2019-09-06 NaN NaN NaN NaN
144 2019-09-07 NaN NaN NaN 220.8571
145 2019-09-08 NaN 119.5500 107.70000 221.5800
146 2019-09-09 143.5692 121.6769 109.85333 223.7350
147 2019-09-10 144.6364 122.5515 110.67419 224.8308
148 2019-09-11 146.0605 123.7308 111.77105 226.1667
这里有更多细节(如评论所愿)
> dput(dd[140:148,1:5])
structure(list(UTC.Time = structure(c(18142,18143,18144,18145,18146,18147,18148,18149,18150),class = "Date"),Punkt.11 = c(133.735294117647,135.076923076923,136.233333333333,NaN,143.569230769231,144.636363636364,146.060526315789),Punkt.13 = c(113.630303030303,114.782926829268,115.991666666667,119.55,121.676923076923,122.551515151515,123.730769230769),Punkt.14 = c(102.262857142857,103.292307692308,103.8,107.7,109.853333333333,110.674193548387,111.771052631579),Punkt.21 = c(212.891176470588,215.25,216.625,220.857142857143,221.58,223.735,224.830769230769,226.166666666667
)),row.names = 140:148,class = "data.frame")
现在我想计算速度为厘米/天。 这是直截了当的,因为我已经有了每天的位移率并且单位已经是厘米。所以基本上它只是值 n (n=Now) 减去值 n-1,n-1 是之前的时间步长。为此,我将计算: (Sn - Sn-1) / (Tn - Tn-1) ,S 是累积间距,T 是日期。
我已经试过了
dd_v <- dd # copy dateframe
dd[,2:ncol(dd)] <- NA # removing everithing but the first col,beeing the date. not pretty,but it works great.
for (r in 2:nrow(dd)) { # row
dd_v[r,2:ncol(dd)] <- abs(
dd[r,2:ncol(dd)] - dd[r-1,2:ncol(dd)]) # delta S
/ (as.numeric(difftime(dd[r,1],dd[r-1,units = c("days")))) # delta T
}
基本上没问题。 然而,现在我为每一个 NaN 得到一个额外的。所以我丢失了很多日期。
> dd_v[140:148,1:5]
UTC.Time Punkt.11 Punkt.13 Punkt.14 Punkt.21
138 2019-09-01 0.9666667 0.7761905 1.0408929 1.3622103
139 2019-09-02 NaN NaN NaN NaN
140 2019-09-03 NaN NaN NaN NaN
141 2019-09-04 1.3416290 1.1526238 1.0294505 2.3588235
142 2019-09-05 1.1564103 1.2087398 0.5076923 1.3750000
143 2019-09-06 NaN NaN NaN NaN
144 2019-09-07 NaN NaN NaN NaN
145 2019-09-08 NaN NaN NaN 0.7228571
146 2019-09-09 NaN 2.1269231 2.1533333 2.1550000
147 2019-09-10 1.0671329 0.8745921 0.8208602 1.0957692
148 2019-09-11 1.4241627 1.1792541 1.0968591 1.3358974
因此,我想进行插值。意义: 我想寻找最接近的非 NaN 值并计算速度,关于更大的跳跃时间。
即:2019-09-08 的 Punkt.13 减去 2019-09-05 的 Punkt.13 除以 3,三天过去了。
我被卡住了。 你能帮我吗?
我尝试过的(从概念上讲,不需要发布我失败的代码):
寻找 dd 最下面的条目(被填充的) 并在计算速度时使用该值的索引作为n-1。 但是,如果不产生错误,我无法完成此操作
#which
#which.max()
或
我也用另一个 for 循环尝试过
library(dplyr)
d <- select(dd,1,c)
# next step: ged rid of NA
# then calculate
# afterwards left_join(…) the multiple slices.
非常感谢您的帮助!
最好的 美联社
解决方法
我想我找到了一种基于此 post 的解决方案。
我已经按照 which(dd %in s) 的逻辑对其进行了调整以找到索引。是搜索条件。
sapply(dd,function(x) which(x %in% x[max(which(!is.na(x)))]))
返回 dd 的最后一个非 NaN 值的位置。
>sapply(dd,function(x) which(x %in% x[max(which(!is.na(x)))]))
UTC.Time Punkt.11 Punkt.13 Punkt.14 Punkt.21
9 9 9 9 9
是的,这个例子并不是最好的,因为每一列在最后一行都有一个条目。但我想坚持这个例子。
就我而言,结果如下所示:
for (c in 2:ncol(dd_v)) { #loop whitout first colums (time stamps)
for ( r in 2:nrow(dd_v)) { #loop of each row,without first one,as initial v is unknown.
rr <- sapply(dd_v[c],function(x) which(x %in% x[max(which(!is.na(x)))]))
if (length(unlist(rr)) > 1) { # if c is empty (multiple NAs),every entry is a maximum,result therefore > 1
rr <- r-1 } # if this is the case,rr sould be the row above
else {} # if not,leave rr as caluclated
dd_v[r,c] <- abs(
(dd[r,c]-dd[rr,c])
/as.numeric(difftime(dd[r,1],dd[rr,units = c("days")))
) # calculates velocity
} # ENDE row Loop
} # ENDE column Loop
不是一个漂亮的代码,当然也不快(作为双循环),但可以完成工作。
如果您有更简洁的解决方案,请贡献。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。