我有两个不同的数据帧,行数不同。我需要将一组函数应用于每个可能的行组合,其中一行来自第一个数据帧,另一行来自第二个数据帧。虽然我能够使用 for 循环执行此任务,但我觉得必须有一种更有效的方法来执行此操作。下面给出一个示例案例。 D1和D2是两个数据帧。我需要用一列作为x-y平面中的欧几里德距离来评估D3,将第二列作为z值的平方差来评估D1和D2中的每一行。
D1<-data.frame(x=1:5,y=6:10,z=rnorm(5))
D2<-data.frame(x=19:30,y=41:52,z=rnorm(12))
D3<-data.frame(distance=integer(0),difference=integer(0))
for (i in 1:nrow(D1)){
for (j in 1:nrow(D2)) {
temp<-data.frame(distance=sqrt(sum((D1[i,1:2]-D2[j,1:2])^2)),difference=(D1[i,3]-D2[j,3])^2)
D3<-rbind(D3,temp)
}
}
谢谢
答案 0 :(得分:0)
合并两个数据帧以通过 -
获取所有唯一组合D3<-merge(D1,D2,by=c())
result<-data.frame(distance=integer(0),difference=integer(0))
然后使用purrr :: map在数据帧D3的所有行中应用相同的距离/差值计算器功能
resdistance<-data.frame(purrr::map(1:nrow(D3),function(ind) { distance=sqrt(sum((D3[ind,]['x.x']-D3[ind,]['x.y'])^2,(D3[ind,]['y.x']-D3[ind,]['y.y'])^2)) }))
resdifference<-data.frame(purrr::map(1:nrow(D3),function(ind) { difference=(D3[ind,]['z.x']-D3[ind,]['z.y'])^2 }))
然后,您可以合并两个数据帧以获得所需的结果
result<-rbind(result,cbind(resdistance,resdifference))
答案 1 :(得分:0)
您可以创建一个单独的函数来相应地计算每个data.frame的索引,这里我称之为i_D1
和i_D2
。
# create function to compute the euclidean distance and z-difference
get_D3_values <- function(i_D1, i_D2){
dist_x <- D1[i_D1, "x"] - D2[i_D2, "x"]
dist_y <- D1[i_D1, "y"] - D2[i_D2, "y"]
distance <- sqrt(dist_x^2 + dist_y^2)
difference <- (D1[i_D1, "z"] - D2[i_D2, "z"])^2
return(
list("i_D1"=i_D1, "i_D2"=i_D2,
"distance"=distance, "difference"=difference)
)
}
之后,创建一个矩阵,将D1
和D2
的所有索引变量与expand.grid
合并。
D1 <- data.frame(x=1:5, y=6:10, z=rnorm(5))
D2 <- data.frame(x=19:30, y=41:52, z=rnorm(12))
# create a data table with all combinations between rows of D1 and D2
row_comb <- expand.grid("row_D1"=seq(nrow(D1)), "row_D2"=seq(nrow(D2)))
head(row_comb)
# row_D1 row_D2
#1 1 1
#2 2 1
#3 3 1
#4 4 1
#5 5 1
#6 1 2
因此,应用mapply
在row_comb
的所有行上迭代函数。
result <- with(row_comb,
mapply(FUN=get_D3_values, i_D1=row_D1, i_D2=row_D2, USE.NAMES=TRUE))
result <- data.frame(t(result))
head(result)
# i_D1 i_D2 distance difference
#1 1 1 39.35734 0.08479992
#2 2 1 38.01316 1.155829
#3 3 1 36.67424 2.858793
#4 4 1 35.34119 0.8642712
#5 5 1 34.0147 0.3030355
#6 1 2 40.70626 2.657727
答案 2 :(得分:0)
还有一个data.table
解决方案:
library(data.table)
setDT(D1)[, rn := .I]
setDT(D2)[, rn := .I]
D1[D2[CJ(D1$rn, D2$rn), on = .(rn == V2)], on = .(rn == V1)][
, .(distance = sqrt((x - i.x)^2 + (y -i.y)^2),
difference = (z - i.z)^2)]