как заменить столбец с разными строками на одну строку R? - PullRequest
0 голосов
/ 08 декабря 2018

У меня есть такой фрейм данных:

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 #", но другими строками, такими как "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..), но хочузаменить все странно отформатированные уровни просто на «уровень 1», «уровень 2», «уровень 3».

Я пробовал это с использованием apply(), для циклов с gsub().Тем не менее, ни один из них, кажется, не работает.Я думаю, что это может быть потому, что gsub() не может взять список?

Я также хотел использовать регулярные выражения, чтобы получить шаблон, используя str_replace(), но я не могу понять, как это сделать.Я никогда не использовал str_replace() и плохо знаком с регулярными выражениями.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

Вот общий подход, позволяющий указывать уровни английскими словами, арабскими или римскими цифрами.Конечный результат всегда имеет формат «Уровень (арабская цифра)».

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, и заменяет эти элементы на "Level lvl".Вызовите эту функцию f(y, lvl).Мы передаем Reduce эту функцию f, вектор уровней lvls и начальный вектор tolower(x).Предположим, что lvls равно 1:3.Затем происходит следующее: r1: = f (x, 1), r2: = f (r1, 2), r3: = f (r2, 3), и все готово: r3 - это конечный результат, где каждый изоб уровнях позаботились.

0 голосов
/ 08 декабря 2018

Если я вас понимаю, это должно сработать.

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