按组分组计算所有几个点的X和Y差异,保留初始列

时间:2018-06-07 06:45:59

标签: r dataframe combinations distance difference

我有一个data.frame,包含坐标和组信息,如下所示:

set.seed(1)
df = data.frame(x=round(runif(6,1,100)), y=round(runif(6,100,200)), group=c("A", "A", "B", "B", "B", "A"))

我想创造一个"差异" data.frame,来自2个点的所有组合,并计算第一列中X坐标的差异,在第二列的Y中。我想出了这个代码绝对没有效率的imo:

comp.diff = function(H, data) {(data[H[1], 1:2]- data[H[2], 1:2])}
comb = df %>% nrow %>% combn(2) %>% {cbind(., .[2:1, ])} # make all combinations in both ways
apply(comb, 2, comp.diff, data = df) %>% do.call('rbind.data.frame', .)

但我不能再做两件事了:

  • 我想计算(或保留)仅从同一组
  • 取得的几对夫妇的差异
  • 我想为输出矩阵中的每一行保留有关初始x,初始y和相关组ID的信息

如何以有效的方式实现这一目标(显然,组合的数量会随着N ...而快速增长) 感谢

预期产出的结构(摘录):

####   delta.x delta.y old.x old.y group
#### 1     -11      28    27   166     A
#### 5     -63      76    27   118     A
#### ...

1 个答案:

答案 0 :(得分:2)

你可以尝试

library(tidyverse)
# calculate the combinations per group
combs <- df %>% 
  split(.$group) %>% 
  map(~combn(1:nrow(.),2)) 

# the calcualtion
df %>% 
  mutate(index=1:n()) %>% 
  split(.$group) %>% 
  map2(combs, ., ~data.frame(t(apply(.x, 2, function(i) 
    cbind(paste(.y$index[i], collapse = "-"),
          .y$x[i[1]],.y$x[i[2]],.y$y[i[1]],.y$y[i[2]],
          -diff(.y$x[i]), -diff(.y$y[i])))),stringsAsFactors = F)) %>% 
  bind_rows(.id = "group") %>% 
  dplyr::select(1, index_diff=2, 
                x1_old=3, x2_old=4,
                y1_old=5, y2_old=6,
                diff_x=7,diff_y=8)

修改

并且在一个管道中共同包括转换为整数

df %>% 
  mutate(index=1:n()) %>% 
  split(.$group) %>% 
  map(~data.frame(t(apply(combn(1:nrow(.),2), 2, function(i) 
    cbind(paste(.$index[i], collapse = "-"),
          .$x[i[1]],.$x[i[2]],.$y[i[1]],.$y[i[2]],
          -diff(.$x[i]), -diff(.$y[i])))),stringsAsFactors = F)) %>% 
  bind_rows(.id = "group") %>% 
  dplyr::select(1, index_diff=2, 
                x1_old=3, x2_old=4,
                y1_old=5, y2_old=6,
                diff_x=7,diff_y=8) %>% 
  mutate_at(vars(x1_old:diff_y), as.numeric) %>% 
  as.tibble()
# A tibble: 6 x 8
  group index_diff x1_old x2_old y1_old y2_old diff_x diff_y
  <chr> <chr>       <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
1 A     1-2            27     38    194    166    -11     28
2 A     1-6            27     90    194    118    -63     76
3 A     2-6            38     90    166    118    -52     48
4 B     3-4            58     91    163    106    -33     57
5 B     3-5            58     21    163    121     37     42
6 B     4-5            91     21    106    121     70    -15