R 语言里面如何使用 nest() 嵌套分类汇总数据

最近有个小伙伴问了这样一个问题,他有很多类似这样的字符串:

123 Main Street St. Louisville OH 43071,432 Main Long Road St. Louisville OH 43071,786 High Street Pollocksville NY 56432

这里面是三个地址:

  • 123 Main Street St. Louisville OH 43071;
  • 432 Main Long Road St. Louisville OH 43071;
  • 786 High Street Pollocksville NY 56432

其中前三个数字表示门牌号,最后的类似 OH 43071 的字符串表示邮编,中间的字符串表示地址,他想把这个字符串整理成这样的数据:

  • OH 43071:Main Street St. Louisville,Main Long Road St. Louisville/123,432;
  • NY 56432:High Street Pollocksville/786

也就是一个邮编下的地址汇总到一起。为此,我们可以设计一段程序输入这种字符串,然后输出一个数据框,这个数据框类似上面的结构。

首先加载 tidyverse 包:

library(tidyverse)

把我们需要处理的字符串存储在 char 中:

"123 Main Street St. Louisville OH 43071,432 Main Long Road St. Louisville OH 43071,786 High Street Pollocksville NY 56432" -> char

首先把地址们使用逗号分隔、转成 tibble 数据框然后从里面提取邮编、地址和门牌号元素:

char %>%
str_split(",") %>%
unlist() %>%
as_tibble() %>%
mutate(v1 = str_sub(value, 1, 3),
v2 = str_match(value, "\\w{2}\\s\\d{5}")[,1],
v3 = str_remove_all(value, v1),
v3 = str_remove_all(v3, v2),
v3 = str_trim(v3, side = "both")) %>%
select(-value) -> df
df
#> # A tibble: 3 x 3
#> v1 v2 v3
#> <chr> <chr> <chr>
#> 1 123 OH 43071 Main Street St. Louisville
#> 2 432 OH 43071 Main Long Road St. Louisville
#> 3 786 NY 56432 High Street Pollocksville

然后按照 v2 nest:

df %>%
nest(-v2) -> df1
df1
#> # A tibble: 2 x 2
#> v2 data
#> <chr> <list>
#> 1 OH 43071 <tibble [2 x 2]>
#> 2 NY 56432 <tibble [1 x 2]>

data 变量的每个观测值都是一个 tibble 数据框,例如第一个 tibble 是这样的:

df1$data[1][[1]]
#> # A tibble: 2 x 2
#> v1 v3
#> <chr> <chr>
#> 1 123 Main Street St. Louisville
#> 2 432 Main Long Road St. Louisville

我们再编写一个函数来处理这个数据框以得到我们需要的字符串:

pfun <- function(x) {
paste(x$v3 %>%
paste0(collapse = ","),
x$v1 %>%
paste0(collapse = ","), sep = "/")
}

pfun(df1$data[1][[1]])
#> [1] "Main Street St. Louisville,Main Long Road St. Louisville/123,432"

最后我们再使用 map_char 进行映射:

df1 %>%
mutate(v4 = map_chr(data, pfun)) %>%
mutate(v4 = paste(v2, v4, sep = ":")) %>%
select(v4)
#> # A tibble: 2 x 1
#> v4
#> <chr>
#> 1 OH 43071:Main Street St. Louisville,Main Long Roa~
#> 2 NY 56432:High Street Pollocksville/786

这个结果就是我们需要的了,是不是也不复杂。

点击这里跳转到 RStata 短书平台获取附件:R 语言里面如何使用 nest() 嵌套分类汇总数据

评论