我想基于纬度和经度两列在R中创建一个唯一ID,以便重复的位置具有相同的群集ID。
例如:
LAT LONG Cluster_ID
13.5330 -15.4180 1
13.5330 -15.4180 1
13.5330 -15.4180 1
13.5330 -15.4180 1
13.5330 -15.4170 2
13.5330 -15.4170 2
13.5330 -15.4170 2
13.5340 -14.9350 3
13.5340 -14.9350 3
13.5340 -15.9170 4
13.3670 -14.6190 5
#1 楼
这是使用interaction
的一种方法。d <- read.table(text='LAT LONG
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4170
13.5330 -15.4170
13.5330 -15.4170
13.5340 -14.9350
13.5340 -14.9350
13.5340 -15.9170
13.3670 -14.6190', header=TRUE)
d <- transform(d, Cluster_ID = as.numeric(interaction(LAT, LONG, drop=TRUE)))
# LAT LONG Cluster_ID
# 1 13.533 -15.418 2
# 2 13.533 -15.418 2
# 3 13.533 -15.418 2
# 4 13.533 -15.418 2
# 5 13.533 -15.417 3
# 6 13.533 -15.417 3
# 7 13.533 -15.417 3
# 8 13.534 -14.935 4
# 9 13.534 -14.935 4
# 10 13.534 -15.917 1
# 11 13.367 -14.619 5
编辑:结合@Spacedman的建议为
drop=TRUE
提供interaction
。#2 楼
在.GRP
1.8.3中添加了data.table
,您可以执行以下操作:# Your data, as a data.frame
dat <- read.table(text='LAT LONG
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4170
13.5330 -15.4170
13.5330 -15.4170
13.5340 -14.9350
13.5340 -14.9350
13.5340 -15.9170
13.3670 -14.6190', header=TRUE)
# Convert it to a data.table
# with keys as the combination of LAT and LONG
library(data.table)
DT <- data.table(dat, key="LAT,LONG")
DT[, Cluster_ID:=.GRP, by=key(DT)]
DT
# LAT LONG Cluster_ID
# 1: 13.367 -14.619 1
# 2: 13.533 -15.418 2
# 3: 13.533 -15.418 2
# 4: 13.533 -15.418 2
# 5: 13.533 -15.418 2
# 6: 13.533 -15.417 3
# 7: 13.533 -15.417 3
# 8: 13.533 -15.417 3
# 9: 13.534 -15.917 4
# 10: 13.534 -14.935 5
# 11: 13.534 -14.935 5
评论
谢谢大家的答复。他们工作得很好,这为我节省了很多时间。创建唯一ID后,我接下来要做的就是复制某些字段并为其他字段创建NA。我的数据以年为单位,并非所有集群都具有所有年份的数据,所以首先我想为所有id填写缺失的年份(1990:2010)。然后填写我添加了年份的其余字段,并为我要预测的其他字段创建NA。
– jonestats
2012年11月27日13:16
#3 楼
数据:dat <- read.table(text="
LAT LONG
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4170
13.5330 -15.4170
13.5330 -15.4170
13.5340 -14.9350
13.5340 -14.9350
13.5340 -15.9170
13.3670 -14.6190", header = TRUE)
这些命令创建一个以
1
开头的id变量:comb <- with(dat, paste(LAT, LONG))
within(dat, Cluster_ID <- match(comb, unique(comb)))
输出:
LAT LONG Cluster_ID
1 13.533 -15.418 1
2 13.533 -15.418 1
3 13.533 -15.418 1
4 13.533 -15.418 1
5 13.533 -15.417 2
6 13.533 -15.417 2
7 13.533 -15.417 2
8 13.534 -14.935 3
9 13.534 -14.935 3
10 13.534 -15.917 4
11 13.367 -14.619 5
#4 楼
比较性能建议的解决方案:df <- read.table(text='LAT LONG
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4180
13.5330 -15.4170
13.5330 -15.4170
13.5330 -15.4170
13.5340 -14.9350
13.5340 -14.9350
13.5340 -15.9170
13.3670 -14.6190', header=TRUE)
f1 <- function(df, cols) {
df$id <- as.numeric(interaction(df[cols], drop = TRUE))
df
}
f2 <- function(df, cols) {
comb <- do.call(paste, c(as.list(df[cols]), sep = "."))
df$id <- match(comb, unique(comb))
df
}
f2(df, 1:2)
#> LAT LONG id
#> 1 13.533 -15.418 1
#> 2 13.533 -15.418 1
#> 3 13.533 -15.418 1
#> 4 13.533 -15.418 1
#> 5 13.533 -15.417 2
#> 6 13.533 -15.417 2
#> 7 13.533 -15.417 2
#> 8 13.534 -14.935 3
#> 9 13.534 -14.935 3
#> 10 13.534 -15.917 4
#> 11 13.367 -14.619 5
microbenchmark::microbenchmark(f1(df, 1:2), f2(df, 1:2))
#> Unit: microseconds
#> expr min lq mean median uq max neval cld
#> f1(df, 1:2) 486.400 510.422 575.26659 573.3945 594.1165 1622.243 100 b
#> f2(df, 1:2) 72.952 79.208 86.09265 83.5275 89.7195 159.740 100 a
评论
在您的互动通话中添加drop = TRUE会为您提供1到5之间的数字,而不是您在此处拥有的随机代码。
– Spacedman
2012年11月26日16:28
好的,顺便问一下我还有一个问题。我的数据应该包含1990:2010的年份,但是对于大多数集群而言,有些年份是缺失的。我希望R搜索缺少的内容,然后填写。此外,我还想为响应变量创建NA,并在已创建的新案例中复制其他变量。如果可以的话请帮助。谢谢,琼斯
– jonestats
2012年11月27日13:47
@ user1835888评论不是问的最佳地方。通过可复制的示例发布另一个问题,以显示您尝试过的操作,然后有人会帮助您。
–马修·普洛德(Matthew Plourde)
2012年11月27日13:49