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

问题描述 投票:-2回答:1

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'))

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

r regex country
1个回答
2
投票

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

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

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

如果你有超过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))))
© www.soinside.com 2019 - 2024. All rights reserved.