首页 > 解决方案 > 识别电话号码,然后匹配国家代码,然后在列中分配正确的名称

问题描述

我有一个“CDR”(呼叫详细记录)数据框,其中包含电话号码的前 5 位数字和另一个名为“CC”的数据框,其中包含国家代码和国家名称。

PhoneNumber <- c("52431", "44781", "N/A") #18 million rows of data
CDR <- data.frame(PhoneNumber)               
CDR

CountryCode <- c("52", "44")
CountryName <- c("Mexico", "UK")
cc <- data.frame(CountryName, CountryCode)
cc

#The output I desire
C_CountryName <- c("Mexico", "UK", "N/A")
CDR <- data.frame(PhoneNumber, C_CountryName)
CDR

我是这样想的:

x <- 1
for(x == 2)
{index of y <- cc$CountryCode where (cc$CountryCode == x) (assigns country 
code to y)
y is then matched in all rows of CDR$PhoneNumber and returns index of 
CDR$PhoneNumbers where y is a partial match of CDR$PhoneNumber.
y <- cc$CountryName where (cc$CountryName == x)
x++
}

因此,在循环结束时 x 递增,直到所有国家/地区都匹配,然后我可以将 y 变异为 df1。

我已经尝试过、替换、匹配、grepl、str_detect 几种组合,但我无法获得所需的输出。

我希望你能指引我正确的方向。

标签: rdataframedata-sciencedata-cleaning

解决方案


在 1800 万行数据上运行一组正则表达式模式效率极低,正如其他评论者已经指出的那样,国家/地区呼叫代码可能多于或少于 2 位数字,因此您可能会遇到其他重大问题。话虽如此,您可以使用其中一个apply函数系列通过其中一个函数系列运行每一行数据,grep以匹配任意长的开头数字,如下所示......

PhoneNumber <- c("52431", "44781", "1512234", "21234567", "N/A")
CountryCode <- c("52", "44", "1", "212")
CountryName <- c("Mexico", "UK", "USA", "Morocco")

regex <- paste0("^", CountryCode)

matchname <- 
  sapply(PhoneNumber, USE.NAMES = FALSE, function(x) {
    matches <- sapply(regex, function(y) grepl(y, x))
    if (any(matches)) {
      CountryName[matches]
    } else {
      NA_character_
    }
  })

data.frame(PhoneNumber, matchname)
#   PhoneNumber matchname
# 1       52431    Mexico
# 2       44781        UK
# 3     1512234       USA
# 4    21234567   Morocco
# 5         N/A      <NA>

如果一个国家/地区的呼叫代码加上电话号码的第一个数字左右与另一个国家/地区的呼叫代码匹配,您可能会遇到问题,但据我了解,国家/地区呼叫代码和区号通常旨在避免这种情况。

我建议首先寻找一种可靠的方法将国家/地区呼叫代码与您的电话号码分开,然后对您的国家/地区呼叫代码向量的级别进行精确匹配,以使其更加高效。


推荐阅读