【问题标题】:Package countrycode and regex打包国家代码和正则表达式
【发布时间】:2017-12-22 16:05:04
【问题描述】:

R 包“countrycode”包含一个数据框 (countrycode_data),其中还包含一个名为“country.name.en.regex”的变量。此变量包含我想使用的正则表达式模式,以便创建一个新列,该列是 TRUE 或 FALSE,具体取决于国家名称或其变体是否出现在某些列中,请参见下面的示例。

AB <- c('CHINAS PARTY CONGRESS','JAPAN-US RELATIONS','JAPAN TRIES TO')
TI <- c('AMERICAN FOREIGN POLICY', 'CHINESE ATTEMPTS TO', 'BRITAIN HAS TEA')
AU <- c('AUTHOR 1', 'AUTHOR 2','AUTHOR 3')
M  <- data.frame(AB,TI,AU)
M$Japan<- !!rowSums(sapply(M[c(1:3)], grepl, pattern ='JAPAN'))

日本的正则表达式当然很简单,但也有更复杂的情况。例如,

> M$Czech_Republic<- !!rowSums(sapply(M[c(3, 7:9)], grepl, pattern ="^(?=.*REP).*CZECH|CZECHIA|BOHEMIA"))

在这种情况下,我确实收到以下错误:

Error in FUN(X[[i]], ...) : 
  invalid regular expression '^(?=.*REP).*CZECH|CZECHIA|BOHEMIA', reason 'Invalid regexp'
> 

我现在已经测试了所有提供的正则表达式,并意识到那些不起作用的往往包含

^(?=.* 或 ^(?!.*

我还注意到,例如单词边界没有用两个反斜杠转义(即原始中的 \B 而不是 \B)。有没有我不知道的简单解决方案?还是另一种替代方法?以下是一些返回错误的正则表达式的完整示例:

M$China<- !!rowSums(sapply(M[c(3, 7:9)], grepl, pattern ="^(?!.*\\BMAC)(?!.*\\BHONG)(?!.*\\BTAI)(?!.*\\BREP).*CHINA|^(?=.*PEO)(?=.*REP).*CHINA"))
M$United_States_of_America<- !!rowSums(sapply(M[c(3, 7:9)], grepl, pattern ="UNITED.?STATES\\B(?!.*ISLANDS)|\\BU\.?S\.?A\.?\\B|^\S*U\.?S\.?\\B(?!.*ISLANDS)"))
M$Republic_of_Korea<- !!rowSums(sapply(M[c(3, 7:9)], grepl, pattern ="^(?!.*D.*P.*R)(?!.*DEMOCRAT)(?!.*PEOPLE)(?!.*NORTH).*\\BKOREA(?!.*D.*P.*R)"))

谢谢! SCW

【问题讨论】:

  • 要使前瞻模式起作用,请添加perl=TRUE。此外,您想要的捷克正则表达式应类似于 "^(?=.*REP).*(?:CZECH(?:IA)?|BOHEMIA)"
  • 谢谢,维克托。我没有想到 Perl,但它似乎成功了。为什么必须更改捷克正则表达式?
  • 只是习惯的力量。我认为^(?=.*REP).* 指的是CZECH|CZECHIA|BOHEMIA 中的所有替代品

标签: r regex country


【解决方案1】:

(?=.*REP) 构造是正向前瞻,默认基本 R 正则表达式引擎 (TRE) 不支持。要使用它们,您需要使用perl=TRUE,以便使用 PCRE 正则表达式引擎来处理模式。

但是,请注意^(?=.*REP).*CZECH|CZECHIA|BOHEMIA 可以重写以与 TRE 正则表达式引擎一起使用:

REP.*CZECH|CZECH.*REP|CZECHIA|BOHEMIA
^^^^^^^^^^^^^^^^^^^^^

如果您有超过 1 个肯定的前瞻,那么这种方法可能会被证明是乏味的,而且实际上效率更低。

【讨论】:

    【解决方案2】:

    看起来你应该能够更容易地做到这一点,只需按预期使用 countrycode 包......

    AB <- c('CHINAS PARTY CONGRESS','JAPAN-US RELATIONS','JAPAN TRIES TO')
    TI <- c('AMERICAN FOREIGN POLICY', 'CHINESE ATTEMPTS TO', 'BRITAIN HAS TEA')
    AU <- c('AUTHOR 1', 'AUTHOR 2','AUTHOR 3')
    M  <- data.frame(AB,TI,AU)
    
    library(countrycode)
    
    M$Japan <- apply(M[1:3], 1, function(x) "JPN" %in% countrycode(x, "country.name", "iso3c", warn = FALSE))
    M$China <- apply(M[1:3], 1, function(x) "CHN" %in% countrycode(x, "country.name", "iso3c", warn = FALSE))
    M$UnitedStates <- apply(M[1:3], 1, function(x) "USA" %in% countrycode(x, "country.name", "iso3c", warn = FALSE))
    M$UnitedKingdom <- apply(M[1:3], 1, function(x) "GBR" %in% countrycode(x, "country.name", "iso3c", warn = FALSE))
    M$Czechia <- apply(M[1:3], 1, function(x) "CZE" %in% countrycode(x, "country.name", "iso3c", warn = FALSE))
    M$Korea <- apply(M[1:3], 1, function(x) "KOR" %in% countrycode(x, "country.name", "iso3c", warn = FALSE))
    

    或者一口气完成所有这些,比如......

    countries <- c("JPN", "CHN", "USA", "GBR", "CZE", "KOR")
    M <- cbind(M, 
          sapply(countries, function(iso3c) 
            apply(M[1:3], 1, function(x) 
              iso3c %in% countrycode(x, "country.name", "iso3c", warn = FALSE))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      • 2021-09-01
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      • 2020-12-15
      相关资源
      最近更新 更多