打包国家代码和正则表达式

时间:2017-12-22 16:05:04

标签: r regex country

R-package“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'))

enter image description here

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

> 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

2 个答案:

答案 0 :(得分:2)

(?=.*REP)构造是一个积极的先行,默认的基础R正则表达式引擎(TRE)不支持。要使用它们,您需要使用perl=TRUE,以便使用PCRE正则表达式引擎来处理模式。

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

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

如果你的前瞻性超过1,那么这种做法可能会很乏味,实际上效率更低。

答案 1 :(得分:0)

似乎您只需要按预期使用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))))