r - 通过按子组比较来限制模糊字符串比较的数量

标签 r dplyr memory-efficient fuzzy-comparison fuzzyjoin

我有两个数据集,如下:

DT1 <- structure(list(Province = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3), Year = c(2000, 
2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002, 2000, 2000, 2000, 
2001, 2001, 2001, 2002, 2002, 2002, 2000, 2000, 2000, 2001, 2001, 
2001, 2002, 2002, 2002), Municipality = c("Something", "Anything", 
"Nothing", "Something", "Anything", "Nothing", "Something", "Anything", 
"Nothing", "Something", "Anything", "Nothing", "Something", "Anything", 
"Nothing", "Something", "Anything", "Nothing", "Something", "Anything", 
"Nothing", "Something", "Anything", "Nothing", "Something", "Anything", 
"Nothing"), Values = c(0.59, 0.58, 0.66, 0.53, 0.94, 0.2, 0.86, 
0.85, 0.99, 0.59, 0.58, 0.66, 0.53, 0.94, 0.2, 0.86, 0.85, 0.99, 
0.59, 0.58, 0.66, 0.53, 0.94, 0.2, 0.86, 0.85, 0.99)), row.names = c(NA, 
-27L), class = c("tbl_df", "tbl", "data.frame"))

DT2 <- structure(list(Province = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3), Year = c(2000, 
2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002, 2000, 2000, 2000, 
2001, 2001, 2001, 2002, 2002, 2002, 2000, 2000, 2000, 2001, 2001, 
2001, 2002, 2002, 2002), Municipality = c("Some", "Anything", 
"Nothing", "Someth.", "Anything", "Not", "Something", "Anything", 
"None", "Some", "Anything", "Nothing", "Someth.", "Anything", 
"Not", "Something", "Anything", "None", "Some", "Anything", "Nothing", 
"Someth.", "Anything", "Not", "Something", "Anything", "None"
), `Other Values` = c(0.41, 0.42, 0.34, 0.47, 0.0600000000000001, 
0.8, 0.14, 0.15, 0.01, 0.41, 0.42, 0.34, 0.47, 0.0600000000000001, 
0.8, 0.14, 0.15, 0.01, 0.41, 0.42, 0.34, 0.47, 0.0600000000000001, 
0.8, 0.14, 0.15, 0.01)), row.names = c(NA, -27L), class = c("tbl_df", 
"tbl", "data.frame"))

我正在尝试按如下方式匹配它们,建议this link ,作者:Arthur Yip。

library(fuzzyjoin); library(dplyr);
stringdist_join(DT1, DT2, 
                by = "Municipality",
                mode = "left",
                ignore_case = TRUE, 
                method = "jw", 
                max_dist = 10, 
                distance_col = "dist") %>%
  group_by(Municipality.x) %>%
  top_n(1, -dist)

问题是代码完全烧毁了我的计算机,所以我想将代码分成几组以限制字符串比较的数量。我尝试过:

library(fuzzyjoin); library(dplyr);
stringdist_join(DT1, DT2, 
                by = c("Municipality","Year", "State"),
                mode = "left",
                ignore_case = TRUE, 
                method = "jw", 
                max_dist = 10, 
                distance_col = "dist") %>%
  group_by(Municipality.x) %>%
  top_n(1, -dist)

stringdist_join(DT1, DT2, 
                by = "Municipality",
                mode = "left",
                ignore_case = TRUE, 
                method = "jw", 
                max_dist = 10, 
                distance_col = "dist") %>%
  group_by(Municipality, Year, Province) %>%
  top_n(1, -dist)

但是两者都给了我以下各自的错误:

Error: All columns in a tibble must be vectors.
x Column `col` is NULL.
Run `rlang::last_error()` to see where the error occurred.

还有:

Error: Must group by variables found in `.data`.
* Column `Municipality` is not found.
* Column `Year` is not found.
* Column `Province` is not found.
Run `rlang::last_error()` to see where the error occurred.

执行此操作的正确方法是什么?

最佳答案

您的方向是正确的 - 只有一些拼写错误/错误,您需要完成列名称的更改/替换。

此外,在第一个中,您需要弄清楚如何根据 Municipality.dist、Province.dist 和 Year.dist 选择“最佳匹配”。

如果您先弄清楚年份和省份,也许第二个效果更好。


DT1 <- structure(list(Province = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3), Year = c(2000, 2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002, 2000, 2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002, 2000, 2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002), Municipality = c("Something", "Anything", "Nothing", "Something", "Anything", "Nothing", "Something", "Anything", "Nothing", "Something", "Anything", "Nothing", "Something", "Anything", "Nothing", "Something", "Anything", "Nothing", "Something", "Anything", "Nothing", "Something", "Anything", "Nothing", "Something", "Anything", "Nothing"), Values = c(0.59, 0.58, 0.66, 0.53, 0.94, 0.2, 0.86, 0.85, 0.99, 0.59, 0.58, 0.66, 0.53, 0.94, 0.2, 0.86, 0.85, 0.99, 0.59, 0.58, 0.66, 0.53, 0.94, 0.2, 0.86, 0.85, 0.99)), row.names = c(NA, -27L), class = c("tbl_df", "tbl", "data.frame"))

DT2 <- structure(list(Province = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3), Year = c(2000, 2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002, 2000, 2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002, 2000, 2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002), Municipality = c("Some", "Anything", "Nothing", "Someth.", "Anything", "Not", "Something", "Anything", "None", "Some", "Anything", "Nothing", "Someth.", "Anything", "Not", "Something", "Anything", "None", "Some", "Anything", "Nothing", "Someth.", "Anything", "Not", "Something", "Anything", "None"), `Other Values` = c(0.41, 0.42, 0.34, 0.47, 0.0600000000000001, 0.8, 0.14, 0.15, 0.01, 0.41, 0.42, 0.34, 0.47, 0.0600000000000001, 0.8, 0.14, 0.15, 0.01, 0.41, 0.42, 0.34, 0.47, 0.0600000000000001, 0.8, 0.14, 0.15, 0.01)), row.names = c(NA, -27L), class = c("tbl_df", "tbl", "data.frame"))

library(fuzzyjoin); library(dplyr);

stringdist_join(DT1, DT2, 
                by = c("Municipality", "Year", "Province"),
                mode = "left",
                ignore_case = TRUE, 
                method = "jw", 
                max_dist = 10, 
                distance_col = "dist") %>%
    group_by(Municipality.x) %>%
    slice_min(Municipality.dist)
#> # A tibble: 135 x 12
#> # Groups:   Municipality.x [3]
#>    Province.x Year.x Municipality.x Values Province.y Year.y Municipality.y
#>         <dbl>  <dbl> <chr>           <dbl>      <dbl>  <dbl> <chr>         
#>  1          1   2000 Anything        0.580          1   2000 Anything      
#>  2          1   2000 Anything        0.580          1   2001 Anything      
#>  3          1   2000 Anything        0.580          1   2002 Anything      
#>  4          1   2000 Anything        0.580          2   2000 Anything      
#>  5          1   2000 Anything        0.580          2   2001 Anything      
#>  6          1   2000 Anything        0.580          2   2002 Anything      
#>  7          1   2000 Anything        0.580          3   2000 Anything      
#>  8          1   2000 Anything        0.580          3   2001 Anything      
#>  9          1   2000 Anything        0.580          3   2002 Anything      
#> 10          1   2001 Anything        0.94           1   2000 Anything      
#> # ... with 125 more rows, and 5 more variables: `Other Values` <dbl>,
#> #   Municipality.dist <dbl>, Province.dist <dbl>, Year.dist <dbl>, dist <lgl>

stringdist_join(DT1, DT2, 
                by = "Municipality",
                mode = "left",
                ignore_case = TRUE, 
                method = "jw", 
                max_dist = 10, 
                distance_col = "dist") %>%
    group_by(Municipality.x, Year.x, Province.x) %>%
    slice_min(dist)
#> # A tibble: 135 x 9
#> # Groups:   Municipality.x, Year.x, Province.x [27]
#>    Province.x Year.x Municipality.x Values Province.y Year.y Municipality.y
#>         <dbl>  <dbl> <chr>           <dbl>      <dbl>  <dbl> <chr>         
#>  1          1   2000 Anything        0.580          1   2000 Anything      
#>  2          1   2000 Anything        0.580          1   2001 Anything      
#>  3          1   2000 Anything        0.580          1   2002 Anything      
#>  4          1   2000 Anything        0.580          2   2000 Anything      
#>  5          1   2000 Anything        0.580          2   2001 Anything      
#>  6          1   2000 Anything        0.580          2   2002 Anything      
#>  7          1   2000 Anything        0.580          3   2000 Anything      
#>  8          1   2000 Anything        0.580          3   2001 Anything      
#>  9          1   2000 Anything        0.580          3   2002 Anything      
#> 10          2   2000 Anything        0.580          1   2000 Anything      
#> # ... with 125 more rows, and 2 more variables: `Other Values` <dbl>,
#> #   dist <dbl>

由 reprex 软件包 (v0.3.0) 于 2020 年 12 月 7 日创建

关于r - 通过按子组比较来限制模糊字符串比较的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65179975/

相关文章:

r - 在 R 中放大集群/热图

r - 大型数据集最佳实践的内连接

r - 使用 R 和 dplyr 扩展和离散化时间序列数据

c++ - 将 double 值转换为其最简洁的字符串表示形式的最快或最有效的方法是什么?

java - 初始化变量和效率

r - 有效地生成离散随机数

r - tseries - block 引导两个系列相同的重采样顺序

r - 根据R中的条件复制行

R (tidyverse)-用于卡方独立性检验的 2 个 calcategori 变量的聚合数据的列总和?

r - 在数据帧的数字中放置点