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

how to replace a column with different strings to one string R?

我有一个这样的数据框:

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. 

正如你所看到的,其中一些是大写格式,一些在末尾有一个space,一些将"1"标记为数字,字符,甚至用罗马数字。

我知道我可以用 gsub() 写多行,但我想找到一种不那么乏味的方法来解决这个问题。

此数据框还包含与 2 级和 3 级相同的问题(例如 "level 2", "level III ", "level II", "Level Two", "level three","Level TWO")。此外,此数据还包括不只是 "level #" 的字符串,还包括 "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..) 之类的字符串,而是想将所有格式奇怪的级别替换为 "Level 1"、"Level 2" , "Level 3".

我尝试使用 apply(),使用 gsub() 进行循环。但是,其中 none 似乎有效。我想这可能是因为 gsub() 无法上榜?

我也想使用正则表达式来获取使用 str_replace() 的模式,但我不知道该怎么做。我从未使用过 str_replace() 并且是正则表达式的新手。

有什么想法吗?

如果我理解你的意思,这应该有用。

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

这里有一个通用的方法,允许级别用英语单词、阿拉伯数字或罗马数字表示。最终输出始终采用 "Level (Arabic numeral)".

格式
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)( |$)"

意思是我们寻找空格and/or 句子beginning/end 旁边的132 或cxxxii 或一百三十二。一切都以小写形式完成。

现在 fixLevels 使用 givePattern。匿名函数

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

获取一些向量 y,在存在某种形式级别 lvl 的位置找到其元素,并将这些元素替换为 "Level lvl"。调用此函数 f(y, lvl)。我们将此函数 f、级别向量 lvls 和初始向量 tolower(x) 传递给 Reduce。假设 lvls1:3。然后会发生以下情况:r1 := f(x, 1), r2 := f(r1, 2), r3 := f(r2, 3),我们完成了:r3 是最终输出,其中每个级别得到了照顾。