2010-02-14 7 views
288

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

> 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". Совпадение не работает.

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

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

+1

Я только что увидел, что 'sub()' также использует нотацию Perl. Извини за это. Я попытаюсь использовать эту функцию. Но для моего первого вопроса у меня пока нет решения. – mropa

+4

Как заметил он, это регулярное выражение «^ \\ s + | \\ s + $» будет определять начальное и конечное пробелы. так что x <- gsub («^ \\ s + | \\ s + $", "", x) многие из функций чтения R, которые имеют эту опцию: strip.white = FALSE – Jay

ответ

381

Вероятно, лучшим способом справиться с хвостовым пробельными, когда вам прочитайте файл данных. Если вы используете 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) 

К 'шоу' The пробел Вы можете использовать:

paste(myDummy$country) 

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

+7

Так как hadley указал на это регулярное выражение "^ \\ s + | \\ s + $ "будет определять начальное и конечное пробелы. поэтому x <- gsub («^ \\ s + | \\ s + $", "", x) многие из функций чтения R, которые имеют эту опцию: strip.white = FALSE – Jay

+0

@Jay: Спасибо за подсказку. Я изменил регулярные выражения в своем ответе на использование более коротких «\\ s» вместо «[\ t]». – f3lix

+33

См. Также 'str_trim' в пакете' stringr'. –

8

Используйте 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 + $ "' – hadley

+4

Просто хотелось указать, что нужно использовать 'gsub' вместо' sub' с regexp от hadley. С 'sub' он будет разделять пробельные пробелы только в том случае, если нет начального пробела ... – f3lix

+0

Не знал, что вы можете использовать \ s и т. Д. С perl = FALSE. Документы говорят, что синтаксис POSIX используется в этом случае, но принятый синтаксис на самом деле является надмножеством, определяемым библиотекой регулярных выражений TRE http://laurikari.net/tre/documentation/regex-syntax/ –

9

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 другие варианты.

77

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

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

(заслуга комментатора: Р. хлопок)

+0

Это решение удалило некоторые пробелы мутанта, которые 'trimws()' не удалось удалить. –

+0

@RichardTelford вы могли бы привести пример? Потому что это может считаться ошибкой в ​​триммах. – wligtenberg

21

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

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

Использование:

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

Я бы предпочёл Объявление d ответ в качестве комментария к пользователю56, но все же не способен писать в качестве независимого ответа. Функция Удаление начальные и конечные пробелы может быть достигнуто за счет отделки() из пакета GData, а также: Пример

require(gdata) 
example(trim) 

Использование:

> trim(" Remove leading and trailing blanks ") 
[1] "Remove leading and trailing blanks" 
+0

trim() также работает через пакет «растровый» – Nathan

434

С R 3.2.0 новая функция была введена для удаления/задние: пробела

trimws() 

См: http://stat.ethz.ch/R-manual/R-patched/library/base/html/trimws.html

+2

Это зависит от определения лучшего ответа. Этот ответ приятно знать (+1), но в быстром тесте он не так быстро, как некоторые из альтернатив. – A5C1D2H2I1M1N2O1R2T1

+0

, похоже, не работает для многострочных строк, несмотря на то, что '\ n' находится в классе закрытых символов. 'trimws (" SELECT \ n blah \ n FROM foo; ")' все еще содержит символы новой строки. – Jubbles

+4

@Jubbles Это ожидаемое поведение. В строке, которую вы передаете в trimws, нет пробелов в начале или конце. Если вы хотите удалить передние и конечные пробелы из каждой строки строки, вам сначала придется разделить ее. Например: trimws (strsplit ("SELECT \ n blah \ n FROM foo;", "\ n") [[1]]) – wligtenberg

4

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

> 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 (непустая) строка, первым элементом вывода является «» «», но , если в конце строки есть совпадение, результатом является то же, что и при совпадении.

4

Другим вариантом является использование 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 для получения дополнительной информации.

1

Я создал 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" 
0
myDummy[myDummy$country == "Austria "] <- "Austria" 

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

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

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

1

Лучший метод trimws()

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

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