【问题标题】:Merge two data frames considering a range match between key columns考虑关键列之间的范围匹配合并两个数据框
【发布时间】:2016-05-11 09:46:25
【问题描述】:

我是 R 编程的初学者。我目前正在尝试从包含 X 和 Y 坐标以及站点名称的数据框中检索一些站点名称,并将它们复制到具有特定点的不同数据框中。

    FD <- matrix(data =c(rep(1, 500), rep(0, 500),
                     rnorm(1000, mean = 550000, sd=4000),
                     rnorm(1000, mean = 6350000, sd=20000), rep(NA, 1000)),
             ncol = 4, nrow = 1000, byrow = FALSE)
colnames(FD) <- c('Survival', 'X', 'Y', 'Site') 
FD <- as.data.frame(FD)

shpxt <- matrix(c(526654.7,526810.5 ,6309098,6309187,530405.4,530692,
                  6337699, 6338056,580432.7, 580541.9, 6380246,6380391,
                  585761.3, 585847.6, 6379665, 6379759, 584192.1, 584279.4,
                  6382358, 6382710, 583421.2, 583492.4, 6379356, 6379425,
                  532395.5, 532515.3 , 6336421, 6336587, 534694.6, 534791.2,
                  6335620, 6335740, 536749.8, 536957.5, 6337584, 6338130, 590049.6,
                  590419.4, 6372232, 6372432, 580443, 580756.5, 6386342, 6386473,
                  575263.9, 575413.7, 6380416, 6380530, 584625.1, 584753.9, 6381009,
                  6381335), ncol = 4, nrow = 13, byrow = TRUE)
sites <- c("Brandbaeltet", "Brusaa", "Granly", "Jerup Strand", "Knasborgvej",
           "Milrimvej", "Overklitten", "Oversigtsareal", "Sandmosen",
           "Strandby", "Troldkaer", "Vaagholt", "Videsletengen")
colnames(shpxt) <- c("Xmin", "Xmax", "Ymin", "Ymax")
shpxt <- as.data.frame(shpxt)
shpxt["Sites"] <- sites

我的方法是使用这样的嵌套 for 循环:

    tester <- function(FD, shpxt)
{ for (i in 1:nrow(FD)) for (j in 1:nrow(shpxt))         # Open Function
{ if (FD[i,2] >= shpxt[j,1] | FD[i,2] <= shpxt[j,2] &    # Open Loop
      FD[i,3] >= shpxt[j,3] | FD[i,3] <= shpxt[j,4])
{                                                        # Open Consequent
  FD[i,4]=shpxt[j,5]
  {break}
} else                                                  # Close Consequent
{FD[i,4] <- NA                                          # Open alternative
}                                                      # Close alternative
}                                                      # Close loop
}                                                      # Close function

tester(FD, shpxt)

本质上,我想搜索 FD 中的 X 和 Y 坐标属于哪个站点,并将站点名称复制到 i 行的 FD$Site 中。 当我对我的真实数据运行循环时,我收到以下错误消息:

test(FD, shpxt)
Error in if (FD[i, 2] >= shpxt[j, 1] | FD[i, 2] <= shpxt[j, 2] & FD[i,  : 
  missing value where TRUE/FALSE needed

如何让循环从此处转到循环将所需站点名称复制到我的 FD 的位置?

亲切的问候Thøger

【问题讨论】:

  • 建议:更改问题标题以包含有关地理坐标或经纬度的内容
  • 你的身份一团糟。

标签: r merge


【解决方案1】:

考虑到关键列之间的范围匹配,您希望合并两个数据框。这里有两种解决方案。

使用sqldf

library(sqldf)

output <- sqldf("select * from FD left join shpxt 
                on (FD.X >= shpxt.Xmin and FD.X <= shpxt.Xmax and
                    FD.Y >= shpxt.Ymin and FD.Y <= shpxt.Ymax ) ")

使用data.table

library(data.table)

# convert your datasets in data.table
  setDT(FD) 
  setDT(shpxt)

output <- FD[shpxt, on = .(X >= Xmin , X <= Xmax,                # indicate x range
                           Y >= Ymin , Y <= Ymax), nomatch = NA, # indicate y range
             .(Survival, X, Y, Xmin, Xmax, Ymin, Ymax, Sites )]  # indicate columns in the output

有不同的方法可以解决这个问题,您可以在其他 SO 问题 herehere 中找到它。

ps。请记住,for loop 不一定是最佳解决方案。

【讨论】:

  • 效果很好,非常感谢!从现在开始,我会在提问时尽量准确。
【解决方案2】:

这是在基础 R 中的一次失败尝试——也许有人可以帮助纠正

 getSite <- function(x, y) {
    return (shpxt[x >= shpxt['Xmin'] & x <= shpxt['Xmax'] &
                  y >= shpxt['Ymin'] & y <= shpxt['Ymax'] , "Sites"])
  }

测试一下

   p <- c(Survival=0, X=shpxt[2,1], Y=shpxt[2,3]) 
   getSite(p[['X']],p[['Y']])

正确返回

[1] "Brusaa"

然而

FD$Site<-apply(FD, 1, function(point) {getSite(point[['X']], point[['Y']])})

失败

“$(tmp”中的错误,“站点”,值 = 字符(0)): 替换有0行,数据有1000

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-08
    • 2021-03-04
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    相关资源
    最近更新 更多