簡體   English   中英

R-從不同組中的前一行中減去組中所有行的值並過濾掉行

[英]R- Subtract values of all rows in a group from previous row in different group and filter out rows

在 R 中說我有數據框:

data

frame object  x      y
1     6       150    100
2     6       149    99
3     6       148    98
3     6       140    90
4     6       148.5  97    
4     6       142    93
5     6       147    96    
5     6       138    92
5     6       135    90
6     6       146.5  99
1     7       125    200
2     7       126    197
3     7       127    202
3     7       119    185
4     7       117    183    
4     7       123    199
5     7       115    190    
5     7       124    202
5     7       118    192
6     7       124.5  199  

我想根據(x,y)坐標輸出上一幀中最接近的對象並過濾掉其他對象。 我想找到給定幀中的所有對象與前一幀中的單個對象之間的 x 和 y 差異,並保留最近的對象,同時刪除其余對象。 然后保留的對象將用作下一幀的參考。 只有一個對象的幀將保持原樣。 輸出應該是每幀一個對象:

data

frame object  x      y
1     6       150    100
2     6       149    99
3     6       148    98
4     6       148.5  97    
5     6       147    96    
6     6       146.5  99
1     7       125    200
2     7       126    197
3     7       127    202    
4     7       123    199    
5     7       124    202
6     7       124.5  199  

我們可以創建一個for循環,將條件應用於單個對象,然后使用group_by %>% summarize將其應用於每個對象:

library(dplyr)

keep_closest_frame = function(data) {
  frames = split(data, dd$frame)
  for(i in seq_along(frames)) {
    if(nrow(frames[[i]]) != 1 & i == 1) {
      stop("First frame must have exactly 1 row")
    }
    if(nrow(frames[[i]]) == 1) next
    dists = with(frames[[i]], abs(x - frames[[i - 1]][["x"]]) + abs(y - frames[[i - 1]][["y"]]))
    frames[[i]] = frames[[i]][which.min(dists), ]
  }
  bind_rows(frames)
}


data %>%
  group_by(object) %>%
  summarize(keep_closest_frame(across()))
# # A tibble: 12 × 4
# # Groups:   object [2]
#    object frame     x     y
#     <int> <int> <dbl> <int>
#  1      6     1  150    100
#  2      6     2  149     99
#  3      6     3  148     98
#  4      6     4  148.    97
#  5      6     5  147     96
#  6      6     6  146.    99
#  7      7     1  125    200
#  8      7     2  126    197
#  9      7     3  127    202
# 10      7     4  123    199
# 11      7     5  124    202
# 12      7     6  124.   199

這是一個累積操作,因此將采用迭代方法。 這是一個執行一項操作的簡單函數,假設它只針對一個object

fun <- function(Z, fr) {
  prevZ <- head(subset(Z, frame == (fr-1)), 1)
  thisZ <- subset(Z, frame == fr)
  if (nrow(prevZ) < 1 || nrow(thisZ) < 2) return(Z)
  ind <- which.min( abs(thisZ$x - prevZ$x) + abs(thisZ$y - prevZ$y) )
  rbind(subset(Z, frame != fr), thisZ[ind,])
}

fun(subset(dat, object == 6), 3)
#    frame object     x   y
# 1      1      6 150.0 100
# 2      2      6 149.0  99
# 5      4      6 148.5  97
# 6      4      6 142.0  93
# 7      5      6 147.0  96
# 8      5      6 138.0  92
# 9      5      6 135.0  90
# 10     6      6 146.5  99
# 3      3      6 148.0  98

(不維護順序,可以根據需要輕松排序回原位。)

現在我們可以為數據中的每個object Reduce this。

out <- do.call(rbind,
  lapply(split(dat, dat$object),
         function(X) Reduce(fun, seq(min(X$frame)+1, max(X$frame)), init=X)))
out <- out[order(out$object, out$frame),]
out
#      frame object     x   y
# 6.1      1      6 150.0 100
# 6.2      2      6 149.0  99
# 6.3      3      6 148.0  98
# 6.5      4      6 148.5  97
# 6.7      5      6 147.0  96
# 6.10     6      6 146.5  99
# 7.11     1      7 125.0 200
# 7.12     2      7 126.0 197
# 7.13     3      7 127.0 202
# 7.16     4      7 123.0 199
# 7.18     5      7 124.0 202
# 7.20     6      7 124.5 199

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM