【问题标题】:R: Find missing combinations in X-Y-gridR:在 X-Y 网格中查找缺失的组合
【发布时间】:2019-12-07 00:04:21
【问题描述】:

我有一个由 X 和 Y 坐标组成的大网格,每个坐标代表一个值。但是,网格内的某些组合不存在,请参见附图:

我想用 R 脚本识别缺失的 x-y 组合,但不知道如何执行此操作。获得这些组合的效率如何?

我的数据示例:

df1 <- structure(list(coord_n = c(1065125L, 1065875L, 1064625L, 1064375L, 
    1065625L, 1065375L, 1065625L, 1065125L, 1065625L, 1065125L, 1066125L, 
    1064625L, 1066375L, 1064125L, 1064375L, 1064625L, 1066375L, 1064875L, 
    1066125L, 1066625L, 1064375L, 1065125L, 1066375L, 1066625L, 1065125L, 
    1065875L, 1064125L, 1064375L, 1064125L, 1065875L, 1064625L, 1065125L, 
    1065125L, 1065625L, 1066375L, 1064375L, 1064875L, 1065875L, 1066375L, 
    1066625L, 1064375L, 1064625L, 1066375L, 1065875L, 1065375L, 1065375L, 
    1066625L, 1065375L, 1064625L, 1066625L, 1066125L, 1065625L, 1065375L, 
    1065875L, 1064125L, 1064375L, 1064875L, 1065625L, 1065625L, 1064625L, 
    1064875L, 1065375L, 1065875L, 1065875L, 1066625L, 1065875L, 1064875L, 
    1066625L, 1064875L, 1064125L, 1066125L, 1064375L, 1066375L, 1064125L, 
    1066625L, 1065125L, 1064625L, 1065625L, 1066125L, 1064125L, 1066375L, 
    1066625L, 1066375L, 1064125L, 1064875L, 1065375L, 1064375L, 1065625L, 
    1065875L, 1065375L, 1066375L, 1064875L, 1064375L, 1066625L, 1064375L, 
    1065875L, 1064375L, 1065375L, 1064875L, 1066375L), coord_e = c(2418625L, 
    2419125L, 2421875L, 2418125L, 2421375L, 2422375L, 2421125L, 2418875L, 
    2418625L, 2420375L, 2419375L, 2420625L, 2418875L, 2420625L, 2419125L, 
    2420875L, 2419125L, 2419875L, 2418375L, 2421625L, 2422375L, 2422375L, 
    2422125L, 2422125L, 2420125L, 2421875L, 2421875L, 2420125L, 2422375L, 
    2420625L, 2419625L, 2418375L, 2419625L, 2418375L, 2419875L, 2420875L, 
    2421375L, 2422375L, 2422375L, 2418125L, 2418375L, 2419125L, 2418625L, 
    2418875L, 2419375L, 2421375L, 2421125L, 2419125L, 2418375L, 2419625L, 
    2418875L, 2420125L, 2419875L, 2420375L, 2420375L, 2419875L, 2420375L, 
    2422375L, 2421875L, 2422375L, 2419375L, 2420875L, 2421125L, 2421375L, 
    2419125L, 2419375L, 2421625L, 2418375L, 2418875L, 2418375L, 2420125L, 
    2419625L, 2418375L, 2420125L, 2421375L, 2422125L, 2419875L, 2420375L, 
    2420375L, 2418625L, 2421125L, 2420125L, 2421625L, 2419875L, 2419125L, 
    2420625L, 2418625L, 2419375L, 2420125L, 2418125L, 2420125L, 2418625L, 
    2418875L, 2418625L, 2421125L, 2419875L, 2421375L, 2418875L, 2420875L, 
    2421875L), density_value = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), percentage_free = c(100, 
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
    100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 
    100, 100, 100, 100, 100, 100, 100, 100)), class = c("data.table", 
    "data.frame"), row.names = c(NA, -100L))

【问题讨论】:

  • dput 中删除.internal.selfref = &lt;pointer: 0x102017ee0&gt; ... stackoverflow.com/questions/25533332/…
  • 你的网格分辨率是多少?
  • 每个单元格为 250m x 250m - 坐标代表中心点。
  • 所以如果一个网格从(左下点)(1065125, 2418625) 开始,那么右边和下面(例如东南单元格)的网格是(1065375, 2418875)
  • 不,应该是 1065375 / 2418875。两点之间的距离总是 250 米。

标签: r dataframe matrix data.table


【解决方案1】:

假设每个唯一的coord_ncoord_e 都是可行的,则此方法会找到原始数据中未找到的所有唯一值的组合。

allpossible <- do.call(CJ, lapply(df1[, c("coord_n", "coord_e")], unique))
allpossible
#      coord_n coord_e
#   1: 1064125 2418125
#   2: 1064125 2418375
#   3: 1064125 2418625
#   4: 1064125 2418875
#   5: 1064125 2419125
#  ---                
# 194: 1066625 2421375
# 195: 1066625 2421625
# 196: 1066625 2421875
# 197: 1066625 2422125
# 198: 1066625 2422375

我们将采用所有可能的组合并对原始数据进行anti-join

print(allpossible[!df1, on = c("coord_n", "coord_e")], nrows = 10)
#     coord_n coord_e
#  1: 1064125 2418125
#  2: 1064125 2418875
#  3: 1064125 2419125
#  4: 1064125 2419375
#  5: 1064125 2419625
# ---                
# 94: 1066625 2420375
# 95: 1066625 2420625
# 96: 1066625 2420875
# 97: 1066625 2421875
# 98: 1066625 2422375

演示它的工作原理:

原样的数据图(左)和红色的“缺失”点(右):

library(ggplot2)
ggplot(df1, aes(coord_n, coord_e)) +
  coord_quickmap() + geom_point()
ggplot(df1, aes(coord_n, coord_e)) +
  coord_quickmap() + geom_point() +
  geom_point(data = allpossible[!df1, on = c("coord_n", "coord_e")],
             shape = 1, color = "red", size = 3)

(如果allpossible 中有任何不应该存在的内容,我们会将其视为围绕黑点的红色圆圈:

【讨论】:

  • 还有allpossible &lt;- setDT(df1)[, CJ(coord_n, coord_e, unique=TRUE)] 用于生成所有组合
【解决方案2】:

这是另一种使用dplyrtidyr 来获取丢失的“像素”的方法:

library(dplyr)
library(tidyr)

df1 %>% 
  expand(coord_n = seq(min(df1$coord_n), max(df1$coord_n), 250), 
         coord_e = seq(min(df1$coord_e), max(df1$coord_e), 250)) %>% 
  anti_join(.,df1)

#> Joining, by = c("coord_n", "coord_e")
#> # A tibble: 98 x 2
#>    coord_n coord_e
#>      <dbl>   <dbl>
#>  1 1064125 2418125
#>  2 1064125 2418875
#>  3 1064125 2419125
#>  4 1064125 2419375
#>  5 1064125 2419625
#>  6 1064125 2420875
#>  7 1064125 2421125
#>  8 1064125 2421375
#>  9 1064125 2421625
#> 10 1064125 2422125
#> # ... with 88 more rows


或参考Frank's answerdata.table

missingDT <- function(DT, cols, defs = NULL){
  require(data.table)
  mDT = do.call(CJ, c(DT[, ..cols], list(unique=TRUE)))
  res = DT[mDT, on=names(mDT)]
  if (length(defs)) 
    res[, names(defs) := Map(replace, .SD, lapply(.SD, is.na), defs), .SDcols=names(defs)]
  res[!complete.cases(res), cols, with=FALSE]
} 

missingDT(setDT(df1), cols = c("coord_n", "coord_e"))

#     coord_n coord_e
# 1:  1064125 2418125
# 2:  1064125 2418875
# 3:  1064125 2419125
# 4:  1064125 2419375
# 5:  1064125 2419625
# ---
# 94: 1066625 2420375
# 95: 1066625 2420625
# 96: 1066625 2420875
# 97: 1066625 2421875
# 98: 1066625 2422375
#     coord_n coord_e

【讨论】:

    【解决方案3】:

    使用来自 R 基础的table 的简单方法:

    subset(
      data.frame(
        table(df1$coord_n, df1$coord_e, dnn = c('coord_n', 'coord_e'))
        ),
      Freq == 0
    )[, -3]
    
    #  coord_n coord_e
    #1 1064125 2418125
    #3 1064625 2418125
    #4 1064875 2418125
    #5 1065125 2418125
    #7 1065625 2418125
    #8 1065875 2418125
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多