r - 将数据框粘合在一起
问题描述
V1 V2
1 0 58.3354616 15.1455364
2 0 58.3360446 15.1457141
3 0 58.3364476 15.1458118
4 0 58.3368139 15.1459143
5 0 58.3372234 15.1459975
6 0 58.3380975 15.1460381
7 0 58.339002 15.1459897
8 0 58.339663 15.1457799
9 0 58.3402414 15.145495
10 0 58.3411902 15.1447415
11 0 58.3422411 15.1436215
12 0 58.3433313 15.1419505
13 0 58.3464673 15.136081
14 0 58.3508979 15.1277296
113 9 58.3541105 11.9237896
114 9 58.3534139 11.9305822
10 9693 58.3534139 11.9305822
11 9693 58.3533332 11.9313722
14 9693 58.3532568 11.9321196
12 9693 58.353248 11.9322061
在上面的数据集中,我有一组 V2 坐标(纬度和经度),它们属于某些字符串,显示在 V1 中。我想将那些在结尾和开头分别具有相同坐标的字符串粘合在一起。例如: 9 的结尾坐标与 9693 的开头坐标相同,可以说 9698 是字符串 9 的延续。如何将它们粘合在一起?新字符串的名称无关紧要。
上面的数据集是我拥有的数据集的一个样本。我正在寻找一种方法将我的数据集中包含> 10 ^ 6个观察值的所有此类字符串粘合在一起。
解决方案
这是一个显示您的状况的示例数据集:
dat <- data.frame(
v1 = c(rep(1L, 3) , rep(2L, 3) , rep(3L, 3)) ,
v2 = c(c(1,2,3) , c(3,4,5) , c(6,7,8) ) ,
v3 = c(c(11,12,13), c(13,14,15), c(16,17,18))
)
浮点数相等性的任何测试都存在问题,因为它的基本假设是您可以保证相等(提示:您不能,安全地;请参阅R FAQ 7.31,您可以搜索任何 IEEE-754)。最好的缓解措施是在容忍范围内测试不平等。您需要问自己的问题是“离零差有多接近才足够接近?” ,只有您可以根据您的数据和分析需求来回答这个问题。为了这个论点,我将使用1e-9
; 如果您的数据是纬度/经度,那么这相当于该数据所指示的世界部分的大约 0.15 米(如果那真的是瑞典......如果在其他地方,它可能小于 0.15m)。
无论哪种方式,这是dplyr
一种组合连续“字符串”的方法,我们希望 1 和 2 加入,3 保持不同:
library(dplyr)
tol <- 1e-9
dat %>%
mutate(
lastv1 = dplyr::lag(v1),
same = c(FALSE, diff(v2) < tol & diff(v3) < tol)
) %>%
group_by(v1) %>%
mutate(lastv1 = if_else(any(same), lastv1[1], v1[1])) %>%
ungroup() %>%
mutate(v1 = lastv1) %>%
# filter(!same) %>%
select(-same, -lastv1)
# # A tibble: 9 x 3
# v1 v2 v3
# <int> <dbl> <dbl>
# 1 1 1 11
# 2 1 2 12
# 3 1 3 13
# 4 1 3 13
# 5 1 4 14
# 6 1 5 15
# 7 3 6 16
# 8 3 7 17
# 9 3 8 18
我在那里留下了一个注释filter
:如果你需要减少重复的点,那么取消注释它就会有一个连续的字符串。
解决此问题的另一种方法是计算每组点之间的距离,并根据低于阈值的距离确定您的“相同性”。例如,geosphere::distHaversine
或者更准确地说geosphere::distVincentyEllipsoid
会给你每对点之间的距离。
代替我意识到您只是在比较字符串:(1)我撤回了浮点讨论,因为您在回避它;(2)它稍微改变了一些东西,因为我们没有使用diff
(或公差)。
dat2 <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
V1 V2
0 58.3354616_15.1455364
0 58.3360446_15.1457141
0 58.3464673_15.136081
0 58.3508979_15.1277296
9 58.3541105_11.9237896
9 58.3534139_11.9305822
9693 58.3534139_11.9305822
9693 58.3533332_11.9313722
9693 58.3532568_11.9321196
9693 58.353248_11.9322061")
dat2$V2 <- gsub("_", " ", dat2$V2)
dat2 %>%
mutate(
same = dplyr::lag(V2, default = FALSE) == V2,
lastV1 = dplyr::lag(V1)
) %>%
group_by(V1) %>%
mutate(newV1 = if (any(same)) lastV1[1] else V1[1]) %>%
ungroup() %>%
mutate(V1 = newV1) %>%
# filter(!same) %>%
select(-lastV1, -newV1, -same)
# # A tibble: 10 x 2
# V1 V2
# <int> <chr>
# 1 0 58.3354616 15.1455364
# 2 0 58.3360446 15.1457141
# 3 0 58.3464673 15.136081
# 4 0 58.3508979 15.1277296
# 5 9 58.3541105 11.9237896
# 6 9 58.3534139 11.9305822
# 7 9 58.3534139 11.9305822
# 8 9 58.3533332 11.9313722
# 9 9 58.3532568 11.9321196
# 10 9 58.353248 11.9322061
推荐阅读
- css - 如何使用引导程序以不同的顺序从 1 列到 3 个不同的列排序 div
- c# - VS 2019 Winform 项目和 SQLite 错误:无法加载 DLL 'SQLite.Interop.dll':找不到指定的模块
- angular - 如何解决角度中的“类型对象中不存在属性”错误?
- java - 如何在 Springboot 应用程序中实现非 Springboot 实用程序?
- angular - Angular 9 - 事件发射器不发射
- python - Pandas:使用 For 循环遍历已经按排序顺序排列的列的唯一值
- php - 如何仅显示列内的值并显示它(PHP & MySQL)
- html - 需要一个 div,其中有 2 个左右浮动的图像和 btwn 中的文本,它们要放置在 div 的确切中心
- ansible - 如何在 Ansible 服务器列表上设置组件名称
- c++ - 为什么编译器会抱怨“std::vector
诉(10);对于 (auto& e : v){}" 而 "std::vector 诉(10);for (auto& e : v){}" 编译?