提问人:f0nzie 提问时间:11/8/2023 最后编辑:M--f0nzie 更新时间:11/8/2023 访问量:85
如何一次性从数据集中提取纬度和经度
How would you hoist latitude and longitude from a dataset in one stroke
问:
我最近一直在玩嵌套列表,并且能够从深层次中提取数据。我在功能上遇到了一个小问题。我能够提取 5 个和 7 个地址的纬度和经度,但使用两个单独的命令。我想知道是否可以以提取的方式访问列表结构,并且只需要一个命令。示例如下:tidyr
hoist()
hoist()
lat
lng
library(tidyr)
library(dplyr)
library(repurrrsive)
gmaps_cities_o <- repurrrsive::gmaps_cities
gmaps_cities_o
带输出:
A tibble:5 × 2
city json
<chr> <list>
Houston <list [2]>
Washington <list [2]>
New York <list [2]>
Chicago <list [2]>
Arlington <list [2]>
5 rows
要提取,我必须编写两段代码:lat
lng
# extract lat, long for the first address
gmaps_cities_o %>%
hoist(json,
lat = list("results", 1, "geometry", "location", "lat"),
lng = list("results", 1, "geometry", "location", "lng")
)
输出:
A tibble:5 × 4
city lat lng json
<chr> <dbl> <dbl> <list>
Houston 29.76043 -95.36980 <list [2]>
Washington 47.75107 -120.74014 <list [2]>
New York 40.71278 -74.00597 <list [2]>
Chicago 41.87811 -87.62980 <list [2]>
Arlington 32.73569 -97.10807 <list [2]>
5 rows
对于第二个地址:
# extract lat, long for the second address
gmaps_cities_o %>%
hoist(json,
lat = list("results", 2, "geometry", "location", "lat"),
lng = list("results", 2, "geometry", "location", "lng")
)
带输出:
A tibble:5 × 4
city lat lng json
<chr> <dbl> <dbl> <list>
Houston NA NA <list [2]>
Washington 38.90719 -77.03687 <list [2]>
New York NA NA <list [2]>
Chicago NA NA <list [2]>
Arlington 38.87997 -77.10677 <list [2]>
5 rows
因此,两个单独的操作来获取和五个城市的 7 个地址。lat
lng
我可以提取并使用这段代码:lat
lng
gmaps_cities_o %>%
unnest_wider(json) %>%
unnest_longer(results) %>%
hoist(results,
lat = list("geometry", "location", "lat"),
lng = list("geometry", "location", "lng")
) %>%
select(city, lat, lng)
带输出:
A tibble:7 × 3
city lat lng
<chr> <dbl> <dbl>
Houston 29.76043 -95.36980
Washington 47.75107 -120.74014
Washington 38.90719 -77.03687
New York 40.71278 -74.00597
Chicago 41.87811 -87.62980
Arlington 32.73569 -97.10807
Arlington 38.87997 -77.10677
7 rows
但是我不能在一次操作中做到这一点似乎是不对的。像这样的东西:hoist()
gmaps_cities_o %>%
hoist(json,
lat = list("results", (?), "geometry", "location", "lat"),
lng = list("results", (?), "geometry", "location", "lng")
)
任何有嵌套列表经验的人都会给我一个提示吗?
答:
1赞
I_O
11/8/2023
#1
如果您可以使用 base(递归地将函数应用于列表)而不是 ,您可以执行以下操作rapply
hoist
编辑:包括@SamR有用的评论,并添加了一些重塑:
library(dplyr)
library(repurrrsive)
gmaps_cities_o |>
group_by(city) |>
reframe(prop_value = json |> unlist(),
prop_name = names(prop_value)
) |>
filter(grepl('results\\.geometry\\.location\\.(lat|lng)', prop_name)) |>
## reshape and clean up:
group_by(prop_name, city) |>
mutate(coords_no = row_number(),
prop_name = gsub('.*\\.', '', prop_name)
) |>
pivot_wider(id_cols = c(coords_no, city),
names_from = prop_name,
values_from = prop_value
)
这给了:
## # A tibble: 7 x 4
## coords_no city lat lng
## <int> <chr> <chr> <chr>
## 1 1 Arlington 32.735687 -97.1080656
## 2 2 Arlington 38.8799697 -77.1067698
## 3 1 Chicago 41.8781136 -87.6297982
## 4 1 Houston 29.7604267 -95.3698028
## 5 1 New York 40.7127753 -74.0059728
## 6 1 Washington 47.7510741 -120.7401386
## 7 2 Washington 38.9071923 -77.0368707
评论
1赞
SamR
11/8/2023
这很好!一些潜在的改进:1.应该比 .2. 然后你就不需要在 .3.可以替换为。4. 虽然在这种情况下无关紧要(因为没有prop_name称为例如),但您的正则表达式不应使用方括号,而应使用普通括号,即 .group_by(city)
rowwise()
city = city
reframe()
rapply(json, \(x) x)
unlist(json)
"lta"
"(lat|lng)"
2赞
SamR
11/8/2023
#2
这是受到I_O的好答案的启发,但足以让人偏离,这可能是一个单独的答案。您可以创建一个函数:my_hoist
my_hoist <- function(x, path) {
x_flat <- unlist(x)
x_flat[grepl(paste(path, collapse = "\\."), names(x_flat))]
}
这可以以与 hoist 类似的方式使用,但无需指定索引:
gmaps_cities_o |>
group_by(city) |>
reframe(
lat = my_hoist(json, c("results", "geometry", "location", "lat")),
lng = my_hoist(json, c("results", "geometry", "location", "lng")),
)
# # A tibble: 7 × 3
# city lat lng
# <chr> <chr> <chr>
# 1 Arlington 32.735687 -97.1080656
# 2 Arlington 38.8799697 -77.1067698
# 3 Chicago 41.8781136 -87.6297982
# 4 Houston 29.7604267 -95.3698028
# 5 New York 40.7127753 -74.0059728
# 6 Washington 47.7510741 -120.7401386
# 7 Washington 38.9071923 -77.0368707
评论