如何将具有不同字符串的列替换为一个字符串R?

时间:2018-12-07 22:05:52

标签: r regex str-replace gsub stringr

我有一个像这样的数据框:

levels<- c("level 1", "LEVEL 1", "Level 1 ", "Level I", "Level I ", 
"level one", "Level one", "Level One", "Level 1")
df<- as.data.frame(levels)
> df
 levels
1 level 1
2 LEVEL 1
3 Level 1 #this one has a space at the end. 
4 Level I
5 Level I #this one also has a space at the end. 
6 level one
7 Level one
8 Level One
9 Level 1 #this is the correct format I want. 

如您所见,其中一些是大写格式,其中一些在末尾有空格,其中一些将"1"标为数字,字符,甚至是罗马数字。

我知道我可以使用gsub()编写多行代码,但是我想找到一种不太繁琐的方法来解决此问题。

此数据帧还包括与第2级和第3级相同的问题(例如"level 2", "level III ", "level II", "Level Two", "level three","Level TWO")。此外,此数据还包括不仅是“级别#”的字符串,还包括其他字符串,例如"Level 1 with specifications", "Level 2 with specifications", "Level 3 with specifications", "Level 1 with others included", "Moderate", "Mild", "Severe", etc..

我不想替换诸如("Level 1 with specifications", "Level 2 with specifications", "Level 3 with specifications", "Level 1 with others included", "Moderate", "Mild", "Severe", etc..)之类的字符串,而是希望将所有格式奇特的Levels替换为“ Level 1”,“ Level 2”,“ Level 3”。

我使用apply()进行了此操作,用于gsub()的循环。但是,它们似乎都不起作用。我认为这可能是因为gsub()无法列入名单吗?

我还想使用正则表达式来使用str_replace()来捕获模式,但是我不知道该怎么做。我从未使用过str_replace(),并且对正则表达式不熟悉。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

如果我了解您,那应该可以。

# Make all letters lower case
df$levels = trimws(tolower(df$levels))

# Do the replacements ("|" for OR)
df$levels = gsub("three|iii", "3", df$levels)
df$levels = gsub("two|ii", "2", df$levels)
df$levels = gsub("one|i", "1", df$levels)

# Capitalize first letter
substr(df$levels, 1, 1) = toupper(substr(df$levels, 1, 1))
# Or to only capitalize the word "level"
#df$levels = gsub("level", "Level", df$levels)

答案 1 :(得分:0)

这里是一种通用方法,允许级别使用英语单词,阿拉伯语或罗马数字。最终输出始终为“级别(阿拉伯数字)”格式。

library(english)
givePattern <- function(i)
  paste0("( |^)(", paste(i, tolower(as.character(as.roman(i))), as.character(english(i)), sep = "|"), ")( |$)")
fixLevels <- function(x, lvls)
  Reduce(function(y, lvl) replace(y, grep(givePattern(lvl), y), paste("Level", lvl)), lvls, init = tolower(x))

levels <- c(" level vi  ", "LEVEL Three  ", "   level thirteen", 
            "Level XXI", "level CXXIII", "    level fifty")
fixLevels(levels, 1:150)
# [1] "Level 6"   "Level 3"   "Level 13"  "Level 21"  "Level 123" "Level 50"

fixLevels的第一个参数是字符的向量,而第二个参数是要在指定向量中检查的所有级别的向量。

函数使用gsub来检测任何格式的整数级别i,例如

givePattern(132)
# [1] "( |^)(132|cxxxii|one hundred thirty two)( |$)"

表示我们要寻找132或cxxxii或一百二十二,它们位于空格和/或句子的开头/结尾旁边。一切都以小写形式完成。

现在fixLevels使用givePattern。匿名功能

function(y, lvl) replace(y, grep(givePattern(lvl), y), paste("Level", lvl))

选取某个向量y,找到存在某种形式的级别lvl的元素,然后将这些元素替换为“级别lvl”。调用此功能f(y, lvl)。我们将此功能Reduce,级别f的向量和初始向量lvls传递给tolower(x)。假设lvls1:3。然后发生以下情况:r1:= f(x,1),r2:= f(r1,2),r3:= f(r2,3),我们完成了:r3在最终输出中,其中每个这些水平已得到照顾。