按组计算所有点的 X 和 Y 差异,保留初始列
Compute X and Y differences for all couple of points, by group, keeping initial columns
我有一个 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"))
我想根据 2 个点的所有组合创建一个 "differences" data.frame,并计算第一列 X 坐标和第二列 Y 坐标的差异。我想出了这个在我看来绝对没有效率的代码:
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
#### ...
你可以试试
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
我有一个 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"))
我想根据 2 个点的所有组合创建一个 "differences" data.frame,并计算第一列 X 坐标和第二列 Y 坐标的差异。我想出了这个在我看来绝对没有效率的代码:
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
#### ...
你可以试试
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