我有一个较大的数据框(150000行),其中的X和Y作为df1之类的坐标,如下所示:
df1 <- data.frame(X = c(7.48, 7.82, 8.15, 8.47, 8.80, 9.20, 9.51, 9.83, 10.13, 10.59, 7.59, 8.06, 8.39, 8.87, 9.26, 9.64, 10.09, 10.48, 10.88, 11.45),
Y = c(49.16, 48.78, 48.40, 48.03, 47.65, 47.24, 46.87, 46.51, 46.15, 45.73, 48.70, 48.18, 47.72, 47.20, 46.71, 46.23, 45.72, 45.24, 44.77, 44.23),
ID = c("B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2", "B_1_2"),
TI = c(191.31, 191.35, 191.39, 191.44, 191.48, 191.52, 191.56, 191.60, 191.64, 191.69, 1349.93, 1349.97, 1350.01, 1350.05, 1350.09, 1350.14, 1350.18, 1350.22, 1350.26, 1350.30))
在ID列中,我有大约100-200个唯一ID,在每个唯一ID中,我都有200-300个数据点(行)
我有另一个像df2的数据框,如下所示:
df2 <- data.frame(X = c(7.62, 8.25, 8.95, 9.71, 10.23),
Y = c(49.06, 48.30, 47.55, 46.77, 46.25))
现在,基于df2中的每一行,即x1和y1,我想针对唯一的ID找出df1中最接近的XY,如下所示:
df3 <-
X1 Y1 ID1 TI1 X2 Y2 ID2 TI2 X3 Y3 ID3 TI3 X4 Y4 ID4 TI4 X5 Y5 ID5 TI5
7.48 49.16 B_1 191.31 8.15 48.40 B_1 191.39 8.80 47.65 B_1 191.48 9.51 46.87 B_1 191.56 10.13 46.15 B_1 191.64
7.59 48.70 B_1_2 1349.93 8.06 48.18 B_1_2 1349.97 8.87 47.20 B_1_2 1350.05 9.26 46.71 B_1_2 1350.09 10.09 45.72 B_1_2 1350.18
我已经尝试使用以下代码:
dist12 <- function(row){
dists <- (row[["X"]] - df2$X)^2 + (row[["Y"]]- df2$Y)^2
return(cbind(df2[which.min(dists),], distance = min(dists)))
}
df3 <- cbind(df1, do.call(rbind, lapply(1:nrow(df1), function(x) dist12(df1[x,]))))
该代码通过计算df1和df2数据帧中行之间的距离并组合df1和df2来找到行之间的最小距离。根据此代码,它会将df2的单个XY分配给df1中的多行。但是df2中的单行(XY)只能分配给唯一ID中的行之一。
寻找代码以获取预期的输出(df3),如上所述
提前致谢
这是对data.table性能的一种了解。
library(data.table)
df1=as.data.table(df1)
do.call(cbind,
apply(df2,1,function(i){
df1[,d:=(df1$X-i[1])^2+(df1$Y-i[2])^2]
df1[df1[,.I[d==min(d)],by=ID]$V1]
})
)
X Y ID TI d X Y ID TI d X Y ID TI d
1: 7.48 49.16 B_1 191.31 0.0296 8.15 48.40 B_1 191.39 0.0200 8.80 47.65 B_1 191.48 0.0325
2: 7.59 48.70 B_1_2 1349.93 0.1305 8.06 48.18 B_1_2 1349.97 0.0505 8.87 47.20 B_1_2 1350.05 0.1289
X Y ID TI d X Y ID TI d
1: 9.51 46.87 B_1 191.56 0.0500 10.13 46.15 B_1 191.64 0.0200
2: 9.26 46.71 B_1_2 1350.09 0.2061 10.09 45.72 B_1_2 1350.18 0.3005
之后,是否可以将数据帧拆分为列表,以使列表的一个数据帧中的前5列以及列表的另一个数据帧中的后6至10列,依此类推?
@Kumar我不确定您的意思,您的意思是不使用do.call(cbind)调用吗?这将为您提供带有数据帧的列表。
是的,我正在寻找它,它为我们提供了带有数据框的清单