我有一个嵌套的莫斯科街道地址列表,从嵌套列表转换而来。但是,我进行地理编码的数据帧只有没有邮政编码的地址,而在几百个(33k中)的情况下,地址返回了具有不同邮政编码的同一街道地址的多个结果。这在列表中创建了额外的嵌套,当转换为数据帧时,会导致与初始数据帧的观察数量不同。
只有一个地址的结果具有以下结构: (忽略乱码,R控制台无法正确呈现西里尔文)
structure(list(results = structure(list(address_components = list(
structure(list(long_name = c("4", "óëèöà Áîëüøàÿ Àêàäåìè÷åñêàÿ",
"Ñåâåðíûé àäìèíèñòðàòèâíûé îêðóã", "Ìîñêâà", "Ìîñêâà", "Ðîññèÿ",
"127299"), short_name = c("4", "óë. Áîëüøàÿ Àêàäåìè÷åñêàÿ",
"Ñåâåðíûé àäìèíèñòðàòèâíûé îêðóã", "Ìîñêâà", "Ìîñêâà", "RU",
"127299"), types = list("street_number", "route", c("political",
"sublocality", "sublocality_level_1"), c("locality", "political"
), c("administrative_area_level_2", "political"), c("country",
"political"), "postal_code")), .Names = c("long_name", "short_name",
"types"), class = "data.frame", row.names = c(NA, 7L))),
formatted_address = "óë. Áîëüøàÿ Àêàäåìè÷åñêàÿ, 4, Ìîñêâà, Ðîññèÿ, 127299",
geometry = structure(list(location = structure(list(lat = 55.8176896,
lng = 37.522891), .Names = c("lat", "lng"), class = "data.frame", row.names = 1L),
location_type = "ROOFTOP", viewport = structure(list(
northeast = structure(list(lat = 55.8190385802915,
lng = 37.5242399802915), .Names = c("lat", "lng"
), class = "data.frame", row.names = 1L), southwest = structure(list(
lat = 55.8163406197085, lng = 37.5215420197085), .Names = c("lat",
"lng"), class = "data.frame", row.names = 1L)), .Names = c("northeast",
"southwest"), class = "data.frame", row.names = 1L)), .Names = c("location",
"location_type", "viewport"), class = "data.frame", row.names = 1L),
partial_match = TRUE, place_id = "ChIJ59yLsy1ItUYR5EEBFbFJoSA",
types = list("street_address")), .Names = c("address_components",
"formatted_address", "geometry", "partial_match", "place_id",
"types"), class = "data.frame", row.names = 1L), status = "OK"), .Names = c("results",
"status"))
而具有多个可能地址的结果如下所示:
structure(list(results = structure(list(address_components = list(
structure(list(long_name = c("23", "óëèöà Áîëüøàÿ Àêàäåìè÷åñêàÿ",
"Ñåâåðíûé àäìèíèñòðàòèâíûé îêðóã", "Ìîñêâà", "Ìîñêâà", "Ðîññèÿ",
"127299"), short_name = c("23", "óë. Áîëüøàÿ Àêàäåìè÷åñêàÿ",
"Ñåâåðíûé àäìèíèñòðàòèâíûé îêðóã", "Ìîñêâà", "Ìîñêâà", "RU",
"127299"), types = list("street_number", "route", c("political",
"sublocality", "sublocality_level_1"), c("locality", "political"
), c("administrative_area_level_2", "political"), c("country",
"political"), "postal_code")), .Names = c("long_name", "short_name",
"types"), class = "data.frame", row.names = c(NA, 7L)), structure(list(
long_name = c("23", "óëèöà Áîëüøàÿ Àêàäåìè÷åñêàÿ", "Ñåâåðíûé àäìèíèñòðàòèâíûé îêðóã",
"Ìîñêâà", "Ìîñêâà", "Ðîññèÿ", "125008"), short_name = c("23",
"óë. Áîëüøàÿ Àêàäåìè÷åñêàÿ", "Ñåâåðíûé àäìèíèñòðàòèâíûé îêðóã",
"Ìîñêâà", "Ìîñêâà", "RU", "125008"), types = list("street_number",
"route", c("political", "sublocality", "sublocality_level_1"
), c("locality", "political"), c("administrative_area_level_2",
"political"), c("country", "political"), "postal_code")), .Names = c("long_name",
"short_name", "types"), class = "data.frame", row.names = c(NA,
7L))), formatted_address = c("óë. Áîëüøàÿ Àêàäåìè÷åñêàÿ, 23, Ìîñêâà, Ðîññèÿ, 127299",
"óë. Áîëüøàÿ Àêàäåìè÷åñêàÿ, 23, Ìîñêâà, Ðîññèÿ, 125008"), geometry = structure(list(
location = structure(list(lat = c(55.8169112, 55.826859),
lng = c(37.5202899, 37.529427)), .Names = c("lat", "lng"
), class = "data.frame", row.names = 1:2), location_type = c("ROOFTOP",
"ROOFTOP"), viewport = structure(list(northeast = structure(list(
lat = c(55.8182601802915, 55.8282079802915), lng = c(37.5216388802915,
37.5307759802915)), .Names = c("lat", "lng"), class = "data.frame", row.names = 1:2),
southwest = structure(list(lat = c(55.8155622197085,
55.8255100197085), lng = c(37.5189409197085, 37.5280780197085
)), .Names = c("lat", "lng"), class = "data.frame", row.names = 1:2)), .Names = c("northeast",
"southwest"), class = "data.frame", row.names = 1:2)), .Names = c("location",
"location_type", "viewport"), class = "data.frame", row.names = 1:2),
partial_match = c(TRUE, TRUE), place_id = c("ChIJnVMw7C1ItUYRdfeWEQrXuAk",
"ChIJnbnwOdY3tUYR1_D9pHTqCsI"), types = list("street_address",
"street_address")), .Names = c("address_components",
"formatted_address", "geometry", "partial_match", "place_id",
"types"), class = "data.frame", row.names = 1:2), status = "OK"), .Names = c("results",
"status"))
在第二个列表的结果元素中,每个可能的地址都有一个额外的嵌套级别,当展平时会创建一个"额外的"观察该地址,使cbind()
地理编码结果无法返回到地址列表。我使用以下函数将嵌套列表展平为数据框。当进行额外的嵌套时,如何修改它们以仅占用第一个地址?如果地址不正确,当我稍后与另一个数据帧合并时,将简单地从样本中丢弃建筑物,因此我只关心使每个地理编码的观察与原始数据帧(地址的来源)中的适当行匹配。
flatten_googleway <- function(df) {
require(jsonlite)
res <- jsonlite::flatten(df)
res[, names(res) %in% c("geometry.location_type", "geometry.location.lat",
"geometry.location.lng", "formatted_address")]
}
moscowhousegeo.df <- do.call(rbind, lapply(moscowhouse.list, function(x) {
if (length(x$results) == 0) template_res[1, ] else flatten_googleway(x$results)
}))
##template for NA results
structure(list(formatted_address = character(0), geometry.location_type = character(0),
geometry.location.lat = numeric(0), geometry.location.lng = numeric(0)), .Names = c("formatted_address",
"geometry.location_type", "geometry.location.lat", "geometry.location.lng"
), row.names = integer(0), class = "data.frame")
答案 0 :(得分:0)
lapply()
调用以替换没有结果的所有列表元素,以及x$results$address_components
大于长度1的元素(如返回多个可能结果的情况),我就能解决这个问题。
moscowhousegeo.df <- do.call(rbind, lapply(moscowhouse.list, function(x) {
if (length(x$results) == 0 | length(x$results$formatted_address) > 1) template_res[1, ] else flatten_googleway(x$results)
}))
遗憾的是,我仍然以这种方式丢失了一些数据,但是从给出的选项中确定哪个地址是正确的可能过于耗时,而且在数据集中有如此多的观察结果有点愚蠢。