微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

R:在不同长度且充满 NaN 的 data.frame 中自动偏移 - 确定 df 中每个单元格的最接近的非 NaN 值

如何解决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 举报,一经查实,本站将立刻删除。