如何在R中的数据帧内的每个可能行组合上应用多个函数?

如何在R中的数据帧内的每个可能行组合上应用多个函数?,r,list,function,dataframe,sapply,R,List,Function,Dataframe,Sapply,我有一个坐标数据框(lon,lat) 如何对每个可能的行组合应用多个函数,并在各自的列表中获得结果?我的目标是在每次迭代中使用这些计算,不管输入中的行数是多少 提前感谢您的回答,如果这个问题看起来很傻,请道歉。我看过这么多帖子,但找不到一个我可以理解和复制的解决方案 #两个向量(我稍微修改了一下) # two vectors (I changed them a little bit) lon <- c(505997.627175236, 505597.627175236, 515997.6

我有一个坐标数据框(lon,lat)

如何对每个可能的行组合应用多个函数,并在各自的列表中获得结果?我的目标是在每次迭代中使用这些计算,不管输入中的行数是多少

提前感谢您的回答,如果这个问题看起来很傻,请道歉。我看过这么多帖子,但找不到一个我可以理解和复制的解决方案

#两个向量(我稍微修改了一下)
# two vectors (I changed them a little bit)
lon <- c(505997.627175236, 505597.627175236, 515997.627175236, 505297.627175236)   
lat <- c(7941821.025438220, 7945821.025438220, 7141821.025438220, 7921821.025438220)

# a function for the euclidean distance
eDistance <- function(x1, x2, y1, y2) sqrt((x1-x2)^2 + (y1-y2)^2)

# now we create a dataframe...
df <- data.frame(lon, lat) %>%
    mutate(joinIndex = 1:nrow(.)) # and we add an index column

# ...that looks like this
#        lon     lat joinIndex
# 1 505997.6 7941821         1
# 2 505597.6 7945821         2
# 3 515997.6 7141821         3
# 4 505297.6 7921821         4

# create all combinations of the join indeces
df_combinations <- expand.grid(1:nrow(df), 1:nrow(df))

#    Var1 Var2
# 1     1    1
# 2     2    1
# 3     3    1
# 4     4    1
# 5     1    2
# 6     2    2
# 7     3    2
# 8     4    2
# 9     1    3
# 10    2    3
# 11    3    3
# 12    4    3
# 13    1    4
# 14    2    4
# 15    3    4
# 16    4    4

# and join our dataframe first on one index then on the other
df_final <- df_combinations %>%
    left_join(df, by = c("Var1" = "joinIndex")) %>%
    left_join(df, by = c("Var2" = "joinIndex"))

# and then finally calculate the euclidean distance
df_final %>%
    mutate(distance = eDistance(lon.x, lon.y, lat.x, lat.y))

   Var1 Var2    lon.x   lat.x    lon.y   lat.y  distance
1     1    1 505997.6 7941821 505997.6 7941821      0.00
2     2    1 505597.6 7945821 505997.6 7941821   4019.95
3     3    1 515997.6 7141821 505997.6 7941821 800062.50
4     4    1 505297.6 7921821 505997.6 7941821  20012.25
5     1    2 505997.6 7941821 505597.6 7945821   4019.95
6     2    2 505597.6 7945821 505597.6 7945821      0.00
7     3    2 515997.6 7141821 505597.6 7945821 804067.26
8     4    2 505297.6 7921821 505597.6 7945821  24001.87
9     1    3 505997.6 7941821 515997.6 7141821 800062.50
10    2    3 505597.6 7945821 515997.6 7141821 804067.26
11    3    3 515997.6 7141821 515997.6 7141821      0.00
12    4    3 505297.6 7921821 515997.6 7141821 780073.39
13    1    4 505997.6 7941821 505297.6 7921821  20012.25
14    2    4 505597.6 7945821 505297.6 7921821  24001.87
15    3    4 515997.6 7141821 505297.6 7921821 780073.39
16    4    4 505297.6 7921821 505297.6 7921821      0.00

lonBase R function
combn
一次生成向量元素的组合
m
,并且它可以选择性地对这些组合应用函数
FUN
。由于输入数据是一个
“data.frame”
,因此我将把
行名
2乘以2组合起来

euclidean <- function(k){
  f <- function(x, y) sqrt((x[1] - y[1])^2 + (x[2] - y[2])^2)
  x <- unlist(coord[k[1], 1:2])
  y <- unlist(coord[k[2], 1:2])
  f(x, y)
}

angle <- function(k){ 
  f <- function(x, y) atan2(x[2] - y[2], x[1] - y[1])*(180/pi)
  x <- unlist(coord[k[1], 1:2])
  y <- unlist(coord[k[2], 1:2])
  f(x, y)
}

combn(rownames(coord), 2, euclidean)
#[1]   4019.95 800062.50  20012.25 804067.26  24001.87 780073.39

combn(rownames(coord), 2, angle)
#[1] -84.28941  90.71616  87.99547  90.74110  89.28384 -89.21407

对于快速欧几里德计算,您可以查看

对于另一个函数,您可以执行以下操作

atan2(outer(coord$lat, coord$lat, `-`), outer(coord$lon, coord$lon, `-`))*180/pi

最后,我修改了Georgery提供的代码,但我使用了“combn”而不是“expand.grid”,以避免在将函数应用到最终数据帧时行组合之间重复。我还必须使用包“hablar”中的函数“convert”,以便将数据帧“coord_combn”的因子正确地转换为数值

代码如下:

lon <- c(505997.627175236, 505597.627175236, 515997.627175236, 505297.627175236)   
lat <- c(7941821.025438220, 7945821.025438220, 7141821.025438220, 7921821.025438220)

# dataframe creation + adding of an id column
coord <- data.frame(lon, lat) %>% 
                 mutate(id = 1:nrow(.))

coord_combn <- combn(rownames(coord), 2) # all the possible row combinations
coord_combn <- as.data.frame(t(coord_combn)) # transpose columns into rows
coord_combn <- coord_combn %>% 
                 convert(num(V1, V2)) # factor to numeric

#join our dataframe first on one index then on the other
coord_final <- coord_combn %>%
  left_join(coord, by = c("V1" = "id")) %>%
  left_join(coord, by = c("V2" = "id"))

eDistance <- function(x1, x2, y1, y2) sqrt((x1-x2)^2 + (y1-y2)^2)
eAngle <- function(x1, x2, y1, y2) atan2((y1-y2),(x1-x2))*(180/3.14159265359)

# euclidean distance calculation
coord_final <- coord_final %>% 
                 mutate(distance = eDistance(lon.x, lon.y, lat.x, lat.y)) 
# angle calculation
coord_final <- coord_final %>% 
                 mutate(angle = eAngle(lon.x, lon.y, lat.x, lat.y)) 

谢谢你。我很喜欢你的方法,但结果有点不对劲。我可能弄错了,但我想这与你编写函数的方式有关。@FlorentRumiano你完全正确,更正。
lon <- c(505997.627175236, 505597.627175236,
         515997.627175236, 505297.627175236)   
lat <- c(7941821.025438220, 7945821.025438220,
         7141821.025438220, 7921821.025438220)
coord <- data.frame(lon, lat)
atan2(outer(coord$lat, coord$lat, `-`), outer(coord$lon, coord$lon, `-`))*180/pi
lon <- c(505997.627175236, 505597.627175236, 515997.627175236, 505297.627175236)   
lat <- c(7941821.025438220, 7945821.025438220, 7141821.025438220, 7921821.025438220)

# dataframe creation + adding of an id column
coord <- data.frame(lon, lat) %>% 
                 mutate(id = 1:nrow(.))

coord_combn <- combn(rownames(coord), 2) # all the possible row combinations
coord_combn <- as.data.frame(t(coord_combn)) # transpose columns into rows
coord_combn <- coord_combn %>% 
                 convert(num(V1, V2)) # factor to numeric

#join our dataframe first on one index then on the other
coord_final <- coord_combn %>%
  left_join(coord, by = c("V1" = "id")) %>%
  left_join(coord, by = c("V2" = "id"))

eDistance <- function(x1, x2, y1, y2) sqrt((x1-x2)^2 + (y1-y2)^2)
eAngle <- function(x1, x2, y1, y2) atan2((y1-y2),(x1-x2))*(180/3.14159265359)

# euclidean distance calculation
coord_final <- coord_final %>% 
                 mutate(distance = eDistance(lon.x, lon.y, lat.x, lat.y)) 
# angle calculation
coord_final <- coord_final %>% 
                 mutate(angle = eAngle(lon.x, lon.y, lat.x, lat.y))