R 根据用户定义的函数连接两个数据帧

R 根据用户定义的函数连接两个数据帧,r,join,data.table,plyr,dplyr,R,Join,Data.table,Plyr,Dplyr,我正在尝试(内部)根据我拥有的相似性函数连接两个数据帧。 例如: data1<-data.frame(a=c(1,2,3),lat=c(38.862976,37.878146,36.825658), lon=c(-99.336782,-99.326054,-98.475976)) data2<-data.frame(b=c(10,20),lat=c(38.863412,37.877333), lon=c(-99.336701,-99.325151)) 差不多 data3<-j

我正在尝试(内部)根据我拥有的相似性函数连接两个数据帧。 例如:

data1<-data.frame(a=c(1,2,3),lat=c(38.862976,37.878146,36.825658), lon=c(-99.336782,-99.326054,-98.475976))
data2<-data.frame(b=c(10,20),lat=c(38.863412,37.877333), lon=c(-99.336701,-99.325151))
差不多

data3<-join(a=data1,b=data2,by=c(lat,lon),FUN=are.close(a.lat,a.lon,b.lat,b.lon))
lat/lon属于其中一个表的位置(不管是哪一个,比如第一个)

我检查的所有联接/合并方法都不允许您定义联接是如何发生的。它只允许您指定col1=col2之类的内容


有没有一种计算效率高的方法(不是在两个集合上运行两个循环)?

我不知道有哪个函数可以做到这一点(当然可能有…),所以我会尝试自己编写一些代码。根据数据,这可能很困难。但是,假设夫妇真的很清楚(例如,点1的纬度可能最接近B10,而经度可能更接近B20,等等),这可能是要处理的问题的开始:

data1<-data.frame(a=c(1,2,3),lat=c(38.862976,37.878146,36.825658), lon=c(-99.336782,-99.326054,-98.475976))
data2<-data.frame(b=c(10,20),lat=c(38.863412,37.877333), lon=c(-99.336701,-99.325151))

# calculate which is the closest value
names(data1)=c("a","lat_original","lon_original")
closest=function(x,to=to) to[which.min(abs(to - x))]
data1$lat=sapply(data1$lat_original,function(x) closest(x,to=data2$lat))
data1$lon=sapply(data1$lon_original,function(x) closest(x,to=data2$lon))

# if dataframes are not equally big: remove biggest assigned "closest values" (or doubles?)
if(nrow(data1)!=nrow(data2)) {
  data1$diff=abs(data1$lat-data1$lat_original)+abs(data1$lon-data1$lon_original)
  maxN <- function(x, N=N){
  x=x[!is.na(x)]
  len=length(x)
  if(N>len){
    warning('N greater than length(x).  Setting N=length(x)')
    N=length(x)
  }
  sort(x,partial=len-N+1)[as.numeric(len-N+1):len]
}
data1=data1[!data1$diff %in% maxN(data1$diff,N=nrow(data1)-nrow(data2)),]}

# perhaps check if doubles (two different points of data 1 assigned to the same point in data2)
which(duplicated(paste(data1$lat,data1$lon))==T)

#merge based on those closest values
merge(data1,data2,by=c("lat","lon"))

data1我不知道有什么函数可以做到这一点(当然可能有…),所以我会尝试自己编写一些代码。根据数据,这可能很困难。但是,假设夫妇真的很清楚(例如,点1的纬度可能最接近B10,而经度可能更接近B20,等等),这可能是要处理的问题的开始:

data1<-data.frame(a=c(1,2,3),lat=c(38.862976,37.878146,36.825658), lon=c(-99.336782,-99.326054,-98.475976))
data2<-data.frame(b=c(10,20),lat=c(38.863412,37.877333), lon=c(-99.336701,-99.325151))

# calculate which is the closest value
names(data1)=c("a","lat_original","lon_original")
closest=function(x,to=to) to[which.min(abs(to - x))]
data1$lat=sapply(data1$lat_original,function(x) closest(x,to=data2$lat))
data1$lon=sapply(data1$lon_original,function(x) closest(x,to=data2$lon))

# if dataframes are not equally big: remove biggest assigned "closest values" (or doubles?)
if(nrow(data1)!=nrow(data2)) {
  data1$diff=abs(data1$lat-data1$lat_original)+abs(data1$lon-data1$lon_original)
  maxN <- function(x, N=N){
  x=x[!is.na(x)]
  len=length(x)
  if(N>len){
    warning('N greater than length(x).  Setting N=length(x)')
    N=length(x)
  }
  sort(x,partial=len-N+1)[as.numeric(len-N+1):len]
}
data1=data1[!data1$diff %in% maxN(data1$diff,N=nrow(data1)-nrow(data2)),]}

# perhaps check if doubles (two different points of data 1 assigned to the same point in data2)
which(duplicated(paste(data1$lat,data1$lon))==T)

#merge based on those closest values
merge(data1,data2,by=c("lat","lon"))

data1下面是一种使用
dplyr
的方法。我假设
are.close()
是矢量化的,并返回
TRUE/FALSE
,例如,这将与类似
are.close的函数一起工作。下面是一种使用
dplyr
的方法。我假设
are.close()
是矢量化的,并返回
TRUE/FALSE
,例如,这将与
are.close这样的函数一起工作。我建议使用
outer
来识别满足条件的(a,b)对:

neighbormat <- outer(
  1:nrow(data1),
  1:nrow(data2),
  function(i1,i2){  
    are.close(
      data1$lat[i1],
      data1$lon[i1],
      data2$lat[i2],
      data2$lon[i2]
    )
  }
)
dimnames(neighbormat) <- list(data1$a,data2$b)
要获得满足标准的(a,b)对,请使用

ns <- which(neighbormat,arr.ind=TRUE,use.names=TRUE)
dimnames(ns) <- list(NULL,c("a","b"))

     a b
[1,] 1 1
[2,] 2 1
[3,] 1 2
[4,] 2 2

ns我建议使用
outer
来识别符合标准的(a,b)对:

neighbormat <- outer(
  1:nrow(data1),
  1:nrow(data2),
  function(i1,i2){  
    are.close(
      data1$lat[i1],
      data1$lon[i1],
      data2$lat[i2],
      data2$lon[i2]
    )
  }
)
dimnames(neighbormat) <- list(data1$a,data2$b)
要获得满足标准的(a,b)对,请使用

ns <- which(neighbormat,arr.ind=TRUE,use.names=TRUE)
dimnames(ns) <- list(NULL,c("a","b"))

     a b
[1,] 1 1
[2,] 2 1
[3,] 1 2
[4,] 2 2
ns
ns <- which(neighbormat,arr.ind=TRUE,use.names=TRUE)
dimnames(ns) <- list(NULL,c("a","b"))

     a b
[1,] 1 1
[2,] 2 1
[3,] 1 2
[4,] 2 2