tags:

views:

287

answers:

3
+4  Q: 

Whitespace in R

I am having some troubles with leading and trailing whitespace in a data.frame. Eg I like to take a look at a specific row in a data.frame based on a certain condition:

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

I was wondering why I didn't get the expected output since the country Austria obviously existed in my data.frame. After looking through my code history and trying to figure out what went wrong I tried:

> 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

All I have changed in the command is an additional whitespace after Austria.

Further annoying problems obviously arise. Eg when I like to merge two frames based on the country column. One data.frame uses "Austria " while the other frame has "Austria". The matching doesn't work.

  1. Is there a nice way to 'show' the whitespace on my screen so that i am aware of the problem?
  2. And can I remove the leading and trailing whitespace in R?

So far I used to write a simple Perl script which removes the whitespace but it would be nice if I can somehow do it inside R.

+5  A: 

Probably the best way is to handle the trailing whitespaces when you read your data file. If you use read.csv or read.table you can set the parameterstrip.white=TRUE.

If you want to clean strings afterwards you one of these functions:

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

To use one of these functions on myDummy$country:

 myDummy$country <- trim(myDummy$country)

To 'show' the whitespace you could use:

 paste(myDummy$country)

which will show you the strings surrounded by quotation marks (") making whitespaces easier to spot.

f3lix
@f3lix oh those are some nice tips! thanks!
mropa
As hadley pointed it this regex "^\\s+|\\s+$" will identify leading and trailing whitespace. so x <- gsub("^\\s+|\\s+$", "", x) many of R's read functions as have this option: strip.white = FALSE
Jay
@Jay: Thanks for the hint. I changed the regexps in my answer to use the shorter "\\s" instead of "[ \t]".
f3lix
See also `str_trim` in the `stringr` package.
Richie Cotton
+1  A: 

Use grep or grepl to find observations with whitespaces and sub to get rid of them.

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"  
Jyotirmoy Bhattacharya
Or, a little more succinctly, `"^\\s+|\\s+$"`
hadley
Just wanted to point out, that one will have to use `gsub` instead of `sub` with hadley's regexp. With `sub` it will strip trailing whitespace only if there is no leading whitespace...
f3lix
Didn't know you could use \s etc. with perl=FALSE. The docs say that POSIX syntax is used in that case, but the syntax accepted is actually a superset defined by the TRE regex library http://laurikari.net/tre/documentation/regex-syntax/
Jyotirmoy Bhattacharya
+2  A: 

ad1) To see white spaces you could directly call print.data.frame with modified arguments:

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"

See also ?print.data.frame for other options.

Marek