我想将带有邮政编码的数据离散化为区域
我有角色资料
样品:
zip_code
'45654'
'12321'
'99453'
等
我有6个规则类别:
区域1 - NE:01000-19999
区域2 - SE:20000-39999
3区 - MW:40000-58999,60000-69999
地区4 - SW:70000-79999,85000-88499
地区5 - MT:59000-59999,80000-84999,88900-89999
6区 - PC:90000-99999
我希望我的输出是因子数据:
region
'MW'
'NE'
'PC'
等
显然,我知道很多方法可以对数据进行离散化,但没有一种方法可以干净优雅(如循环,ifelse等)
是否有一种优雅的方法来应用具有6个类别的案例来离散这些数据?
答案 0 :(得分:2)
好吧,凌乱但这可行。我假设您将不得不使用字符对象,因为一些邮政编码以0开头。用邮政编码替换这些数字。
zip_code <- c('1','6','15')
regions <- list(NE = as.character(1:3),
SE = as.character(4:6),
MW = as.character(7:9),
SW = as.character(10:12),
MT = as.character(13:15),
PC = as.character(16:19))
sapply(zip_code, function(x) names(regions[sapply(regions, function(y) x %in% y)]))
1 6 15
"NE" "SE" "MT"
答案 1 :(得分:2)
以下是使用foverlaps(...)
的data.table解决方案以及包zipcode
中的完整美国邮政编码数据库。请注意,您对范围的定义不足:例如,NH中的邮政编码超出NE
范围,PR完全丢失。
library(data.table) # 1.9.4+
library(zipcode)
data(zipcode) # database of US zip codes (a data frame)
zips <- data.table(zip_code=zipcode$zip)
regions <- data.table(region=c("NE" , "SE", "MW", "MW", "SW", "SW", "MT", "MT", "MT", "PC"),
start =c(01000,20000,40000,60000,70000,85000,59000,80000,88900,90000),
end =c(19999,39999,58999,69999,79999,88400,59999,84999,89999,99999))
setkey(regions,start,end)
zips[,c("start","end"):=list(as.integer(zip_code),as.integer(zip_code))]
result <- foverlaps(zips,regions)[,list(zip_code,region)]
result[sample(1:nrow(result),10)] # random sample of the result
# zip_code region
# 1: 27113 SE
# 2: 36101 SE
# 3: 55554 MW
# 4: 91801 PC
# 5: 20599 SE
# 6: 90250 PC
# 7: 95329 PC
# 8: 63435 MW
# 9: 60803 MW
# 10: 07040 NE
foverlaps(...)
以这种方式工作:假设data.table x包含代表范围的列a
和b
(例如a
&lt; = {{1}对于所有行),data.table b
具有列y
和c
,类似地表示范围。然后d
为foverlaps(x,y)
中的每一行找到x
中具有重叠范围的所有行。
在您的情况下,我们将y
参数设置为区域,其中范围是每个(子)区域的开始和结束的zipcodes。然后我们使用实际的邮政编码(转换为整数)设置y
作为原始邮政编码数据库,用于范围的开头和结尾。
x
非常快。在这种情况下,完整的美国邮政编码数据库(> 44,000个邮政编码)在大约23毫秒内得到处理。
答案 2 :(得分:1)
您也可以尝试(使用@Scott Chamberlain的数据)
with(stack(regions), unique(ind[ave(values %in% zip_code, ind, FUN=I)]))
#[1] NE SE MT
#Levels: MT MW NE PC SE SW
或者
library(dplyr)
library(tidyr)
unnest(regions, region) %>%
group_by(region) %>%
filter(x %in% zip_code)
# region x
#1 NE 1
#2 SE 6
#3 MT 15
或者
r1 <- vapply(regions, function(x) any(x %in% zip_code), logical(1))
names(r1)[r1]
#[1] "NE" "SE" "MT"