Как обрезать начальные и конечные пробелы?

276

У меня возникают проблемы с ведущими и конечными пробелами в data.frame. Например, я хотел бы взглянуть на конкретный row в data.frame на основе определенного условия:

> myDummy[myDummy$country == c("Austria"),c(1,2,3:7,19)] 

[1] codeHelper     country        dummyLI    dummyLMI       dummyUMI       
[6] dummyHInonOECD dummyHIOECD    dummyOECD      
<0 rows> (or 0-length row.names)

Мне было интересно, почему я не получил ожидаемого результата, так как страна, очевидно, существовала в моем data.frame. Просматривая мою историю кода и пытаясь выяснить, что пошло не так, я попробовал:

> myDummy[myDummy$country == c("Austria "),c(1,2,3:7,19)]
   codeHelper  country dummyLI dummyLMI dummyUMI dummyHInonOECD dummyHIOECD
18        AUT Austria        0        0        0              0           1
   dummyOECD
18         1

Все, что я изменил в команде, является дополнительным пробелом после Австрии.

Возникают и другие неприятные проблемы. Например, когда мне нравится объединять два кадра на основе столбца страны. Один data.frame использует "Austria ", а другой фрейм имеет "Austria". Соответствие не работает.

  • Есть ли хороший способ "показать" пробел на моем экране, чтобы я знал о проблеме?
  • И могу ли я удалить ведущее и конечное пробелы в R?

До сих пор я писал простой Perl script, который удаляет пробелы, но было бы неплохо, если бы я мог как-то сделать это внутри R.

  • 1
    Я только что увидел, что sub() использует нотацию Perl . Извини за это. Я собираюсь попытаться использовать функцию. Но по моему первому вопросу у меня пока нет решения.
  • 4
    Как указывал Хэдли, это регулярное выражение «^ \\ s + | \\ s + $» будет определять начальные и конечные пробелы. поэтому x <- gsub ("^ \\ s + | \\ s + $", "", x) многие из функций чтения R, так как имеют эту опцию: strip.white = FALSE
Теги:
whitespace
trim
removing-whitespace
builtin

12 ответов

392
Лучший ответ

Вероятно, лучший способ - обработать конечные пробелы при чтении файла данных. Если вы используете read.csv или read.table, вы можете установить параметр strip.white=TRUE.

Если вы хотите очистить строки после этого, вы можете использовать одну из следующих функций:

# returns string w/o leading whitespace
trim.leading <- function (x)  sub("^\\s+", "", x)

# returns string w/o trailing whitespace
trim.trailing <- function (x) sub("\\s+$", "", x)

# returns string w/o leading or trailing whitespace
trim <- function (x) gsub("^\\s+|\\s+$", "", x)

Чтобы использовать одну из этих функций на myDummy$country:

 myDummy$country <- trim(myDummy$country)

Чтобы "показать" пробелы, которые вы могли бы использовать:

 paste(myDummy$country)

который покажет вам строки, окруженные кавычками ("), которые упрощают определение пробелов.

  • 7
    Как указывал Хэдли, это регулярное выражение «^ \\ s + | \\ s + $» будет определять начальные и конечные пробелы. поэтому x <- gsub ("^ \\ s + | \\ s + $", "", x) многие из функций чтения R, так как имеют эту опцию: strip.white = FALSE
  • 0
    @Jay: Спасибо за подсказку. Я изменил регулярные выражения в своем ответе, чтобы использовать более короткое "\\ s" вместо "[\ t]".
Показать ещё 7 комментариев
397

Начиная с R 3.2.0 была введена новая функция для удаления ведущих/конечных пробелов:

trimws()

Смотрите: http://stat.ethz.ch/R-manual/R-patched/library/base/html/trimws.html

  • 2
    Это зависит от определения лучшего ответа. Этот ответ приятно знать о (+1), но в быстром тесте он был не так быстр, как некоторые альтернативы.
  • 0
    похоже, не работает для многострочных строк, несмотря на то, что \n находится в покрытом классе символов. trimws("SELECT\n blah\n FROM foo;") прежнему содержит переводы строк.
Показать ещё 3 комментария
75

Чтобы управлять пробелом, используйте str_trim() в пакете stringr. Пакет имеет руководство от 15 февраля 2011 года и находится в CRAN. Функция также может обрабатывать векторы строк.

install.packages("stringr", dependencies=TRUE)
require(stringr)
example(str_trim)
d4$clean2<-str_trim(d4$V2)

(кредит отправляется комментатору: R. Cotton)

  • 2
    Это решение удалило некоторые мутантные пробелы, которые не удалось удалить trimws() .
  • 1
    @RichardTelford, не могли бы вы привести пример? Потому что это можно считать ошибкой в триммерах.
19

Простая функция для удаления начального и конечного пробелов:

trim <- function( x ) {
  gsub("(^[[:space:]]+|[[:space:]]+$)", "", x)
}

Применение:

> text = "   foo bar  baz 3 "
> trim(text)
[1] "foo bar  baz 3"
8

ad1) Чтобы увидеть белые пробелы, вы можете напрямую вызвать print.data.frame с измененными аргументами:

print(head(iris), quote=TRUE)
#   Sepal.Length Sepal.Width Petal.Length Petal.Width  Species
# 1        "5.1"       "3.5"        "1.4"       "0.2" "setosa"
# 2        "4.9"       "3.0"        "1.4"       "0.2" "setosa"
# 3        "4.7"       "3.2"        "1.3"       "0.2" "setosa"
# 4        "4.6"       "3.1"        "1.5"       "0.2" "setosa"
# 5        "5.0"       "3.6"        "1.4"       "0.2" "setosa"
# 6        "5.4"       "3.9"        "1.7"       "0.4" "setosa"

См. также ?print.data.frame для других параметров.

7

Используйте grep или grepl, чтобы найти наблюдения с пробелами и суб, чтобы избавиться от них.

names<-c("Ganga Din\t","Shyam Lal","Bulbul ")
grep("[[:space:]]+$",names)
[1] 1 3
grepl("[[:space:]]+$",names)
[1]  TRUE FALSE  TRUE
sub("[[:space:]]+$","",names)
[1] "Ganga Din" "Shyam Lal" "Bulbul"  
  • 7
    Или, более кратко, "^\\s+|\\s+$"
  • 4
    Просто хотел бы отметить, что нужно использовать gsub вместо sub с регулярным выражением hadley. С помощью sub он удалит конечные пробелы, только если нет начальных пробелов ...
Показать ещё 1 комментарий
4

Я бы предпочел добавить ответ как комментарий пользователю56, но все же не смог написать в качестве независимого ответа. Удаление ведущих и завершающих пробелов может быть достигнуто с помощью функции trim() из пакета gdata:

require(gdata)
example(trim)

Пример использования:

> trim("   Remove leading and trailing blanks    ")
[1] "Remove leading and trailing blanks"
  • 0
    trim () также работает через пакет "растр"
3

Другим вариантом является использование функции stri_trim из пакета stringi, по умолчанию используется удаление начального и конечного пробелов:

> x <- c("  leading space","trailing space   ")
> stri_trim(x)
[1] "leading space"  "trailing space"

Для удаления только пробелов используйте stri_trim_left. Для удаления только пробелов используйте stri_trim_right. Если вы хотите удалить другие ведущие или завершающие символы, вы должны указать это с помощью pattern =.

См. также ?stri_trim для получения дополнительной информации.

2

Другая связанная проблема возникает, если у вас есть несколько пробелов между входами:

> a <- "  a string         with lots   of starting, inter   mediate and trailing   whitespace     "

Затем вы можете легко разбить эту строку на "реальные" токены, используя регулярное выражение для аргумента split:

> strsplit(a, split=" +")
[[1]]
 [1] ""           "a"          "string"     "with"       "lots"      
 [6] "of"         "starting,"  "inter"      "mediate"    "and"       
[11] "trailing"   "whitespace"

Обратите внимание, что если есть совпадение в начале a (непустая) строка, первый элемент вывода - "", но если в конце строки есть совпадение, то результатом является как и при удалении совпадения.

0

Лучший способ - trimws()

Следующий код будет применять эту функцию для всего кадра данных

mydataframe < - data.frame(lapply (mydataframe, trimws), strAsAsFactors = FALSE)

  • 0
    или df[] <- lapply(df, trimws) чтобы быть более компактным. Но это в обоих случаях приведёт столбцы к символу. df[sapply(df,is.character)] <- lapply(df[sapply(df,is.character)], trimws) для безопасности.
0
myDummy[myDummy$country == "Austria "] <- "Austria"

После этого вам нужно заставить R не распознать "Австрию" как уровень. Предположим, вы также имеете "США" и "Испания" в качестве уровней:

myDummy$country = factor(myDummy$country, levels=c("Austria", "USA", "Spain"))

Немного менее устрашающе, чем самый высокий голос, проголосовавший, но он все равно должен работать.

0

Я создал функцию trim.strings (), чтобы обрезать ведущие и/или конечные пробелы как:

# Arguments:    x - character vector
#            side - side(s) on which to remove whitespace 
#                   default : "both"
#                   possible values: c("both", "leading", "trailing")

trim.strings <- function(x, side = "both") { 
    if (is.na(match(side, c("both", "leading", "trailing")))) { 
      side <- "both" 
      } 
    if (side == "leading") { 
      sub("^\\s+", "", x)
      } else {
        if (side == "trailing") {
          sub("\\s+$", "", x)
    } else gsub("^\\s+|\\s+$", "", x)
    } 
} 

Для иллюстрации

a <- c("   ABC123 456    ", " ABC123DEF          ")

# returns string without leading and trailing whitespace
trim.strings(a)
# [1] "ABC123 456" "ABC123DEF" 

# returns string without leading whitespace
trim.strings(a, side = "leading")
# [1] "ABC123 456    "      "ABC123DEF          "

# returns string without trailing whitespace
trim.strings(a, side = "trailing")
# [1] "   ABC123 456" " ABC123DEF"   

Ещё вопросы

Сообщество Overcoder
Наверх
Меню