r - 在坐标对的数据框中获取坐标对的行数
问题描述
假设我有一个名为“边缘”的点对数据框,比如:
x0 y0 x1 y1
1 2.464286 2.464286 2.583333 1.750000
2 0.700000 3.787500 2.464286 2.464286
3 2.464286 2.464286 3.500000 3.500000
4 3.500000 3.500000 4.300000 3.900000
5 2.250000 4.750000 3.500000 3.500000
数据帧的每一行都是从点 (x0,y0) 到点 (x1,y1) 的边,例如我的第一条边从坐标点 (2.464286,2.464286) 到点 (2.583333,1.750000)
从该数据帧中,我可以轻松地提取另一个数据帧,称之为“顶点”,其中每个点只出现一次:
x y
1 2.464286 2.464286
2 0.700000 3.787500
3 3.500000 3.500000
4 2.250000 4.750000
5 2.583333 1.750000
6 4.300000 3.900000
如何用它出现在数据框“边缘”中的行号标记“顶点”中的每个点,不管是左端点还是右端点?也就是说,我想得到这样的东西:
x y occurrences
1 2.464286 2.464286 1,2,3
2 0.700000 3.787500 2
3 3.500000 3.500000 3,4,5
4 2.250000 4.750000 5
5 2.583333 1.750000 1
6 4.300000 3.900000 4
我尝试使用 %in% 和 which,但它只考虑元素比较,因此具有相同 x 坐标或 y 坐标的两个点可以被视为相同。
此外,这是一个标签化,我必须在我的模拟中做很多次,所以我希望得到一个比基于 for-loop/if 的解决方案更好的解决方案。
解决方案
这是一个使用dplyr
. 可能有一种方法可以清理它,但这应该可以让你大部分时间到达那里。
library(dplyr)
edgedf <- read.table(header = TRUE,stringsAsFactors = FALSE, text = "
x0 y0 x1 y1
2.464286 2.464286 2.583333 1.750000
0.700000 3.787500 2.464286 2.464286
2.464286 2.464286 3.500000 3.500000
3.500000 3.500000 4.300000 3.900000
2.250000 4.750000 3.500000 3.500000")
vertdf <- read.table(header = TRUE,stringsAsFactors = FALSE, text = "
x y
2.464286 2.464286
0.700000 3.787500
3.500000 3.500000
2.250000 4.750000
2.583333 1.750000
4.300000 3.900000")
# Add row numbers
tmp_edgedf <- edgedf %>% mutate(id = 1:n())
# Stack the x0,y0 and x1,y1 coords as x,y then join
# with vertices "vertdf". Grouping by x,y and summarise
# concatenating the row numbers as occurrences.
rbind(tmp_edgedf %>%
select(id, x0, y0) %>%
rename(x = x0, y = y0),
tmp_edgedf %>%
select(id, x1, y1) %>%
rename(x = x1, y = y1)) %>%
right_join(vertdf, by = c("x", "y")) %>%
group_by(x, y) %>%
summarise(occurrences = paste(sort(id), collapse = ",")) %>%
data.frame() # Remove rounding by tibble object.
结果
## x y occurrences
## 1 0.700000 3.787500 2
## 2 2.250000 4.750000 5
## 3 2.464286 2.464286 1,2,3
## 4 2.583333 1.750000 1
## 5 3.500000 3.500000 3,4,5
## 6 4.300000 3.900000 4
编辑
下面是一个变体,也许更简单的解决方案。第一个inner_join
将顶点连接到(x0, y0)
,第二个连接到(x1, y1)
。将行号添加到edgedf
数据结构(临时)以跟踪行号。数据框可以在edgedf
连接之前添加,消除重复添加。
rbind(
inner_join(vertdf,
edgedf %>% transmute(id = 1:n(), x0, y0),
by = c(x = "x0", y = "y0")),
inner_join(vertdf,
edgedf %>% transmute(id = 1:n(), x1, y1),
by = c(x = "x1", y = "y1"))
) %>%
group_by(x,y) %>%
summarise(occurrances = paste(sort(id), collapse = ",")) %>%
data.frame()
推荐阅读
- excel - 将数据从工作表中的单元格复制到另一个工作表中的下一个可用行
- c# - 根据用户角色重定向到某些网页不起作用
- c++ - 为什么 c++ 使用 throw() 关键字来指示函数不会抛出任何异常
- c# - 登录 sql vs files vs aws,这在 c# 应用程序中更快
- java - 龙目岛建造者模式问题
- postgresql - Postgres 远程连接
- javascript - 如何使用 cypress 同时进行 2 个用户之间的端到端测试交互
- objective-c - 如何在 Xcode 11 中启动没有故事板 >= iOS 13 的新项目?
- aurelia - Aurelia 组合,使用具有相同视图的不同视图模型
- c# - 如何使用泛型类型的类型参数作为方法参数的类型?