4

I have a variable of initials, with names erroneously scattered throughout the list. See example structure below:

ID <- c('SPW', 'SM', 'DLS', 'SJ', 'joe.schmoe', 'CEJ', 'teddy.roos', 'GVF', 'MJC',  
        'LH', 'sally.fields') ## Full names shouldn't be there -- only initials.
test <- data.frame(ID)

I want to create a new variable (ID2), that switches out any names with assigned initials. Otherwise, I want ID2 to contain the initials from ID. An example of my currently unsuccessful code will hopefully illustrate:

swfun <- function(x) {
    switch(x,
        'joe.schmoe' = 'JS',
        'teddy.roos' = 'TR',
        'sally.fields' = 'SF',
        as.character(test$ID)
        )
    } ## In other words, I've created a switch function to replace any names   
              ## with requisite initials. I was 'hoping' that the last command   
              ## [as.character(test$ID)] would populate the rest of ID2 with values 
              ## from test$ID.
test$ID2 <- sapply(test$ID, swfun)

Rather than getting test$ID2 <- c('SPW', 'SM', 'DLS', 'SJ', 'JS', 'CEJ', 'TR', 'GVF', 'MJC', 'LH', 'SF'),

I'm getting test$ID2 <- list(NULL, NULL, "TR", NULL, c("SPW", "SM", "DLS", "SJ", "joe.schmoe", "CEJ", "teddy.roos", "GVF", "MJC", "LH", "sally.fields"), "JS", NULL, "SF", NULL, NULL, NULL)

This question is similar to one I asked previously (R: ifelse on string), however with the added variation of populating the rest of the column with values of the previous column. Additionally, I'd like to solve this using switch since I'm still fairly new to that function.

Community
  • 1
  • 1
NiuBiBang
  • 628
  • 1
  • 15
  • 30
  • 1
    Possible duplicate of [Why can't I switch on a String?](http://stackoverflow.com/questions/338206/why-cant-i-switch-on-a-string) – NiuBiBang Apr 22 '16 at 11:23

1 Answers1

2

Just switch that last line in the switch function to use x instead of test$ID

swfun <- function(x) {
    switch(x,
        'joe.schmoe' = 'JS',
        'teddy.roos' = 'TR',
        'sally.fields' = 'SF',
        as.character(x)
        )
    }

Results

> unname(sapply(ID, swfun))
 [1] "SPW" "SM"  "DLS" "SJ"  "JS"  "CEJ" "TR"  "GVF" "MJC"
[10] "LH"  "SF" 

Edit re Vectorize (Frank): If you find yourself sapplying this often, you might consider

swfun2 <- Vectorize(swfun)
unname(swfun2(ID))
 [1] "SPW" "SM"  "DLS" "SJ"  "JS"  "CEJ" "TR"  "GVF" "MJC"
[10] "LH"  "SF" 

or the alternative linked in the comments below.

Frank
  • 66,179
  • 8
  • 96
  • 180
Ricardo Saporta
  • 54,400
  • 17
  • 144
  • 178
  • 1
    You could also use `swfun <- Vectorize(...` and then use `swfun(ID)` directly. – Frank Sep 23 '13 at 02:28
  • 2
    @Frank, I wouldnt use `switch` at all, I would just used a named vector. Much easiier – Ricardo Saporta Sep 23 '13 at 02:29
  • Ok. These days I tend to make a labeled list or character vector, take `data.frame(names(x),x)` and merge it in, filling in a default value at the end. – Frank Sep 23 '13 at 02:45
  • @Frank... I dont follow. What is the advantage/utility there? What could you do with the data.frame that you could not already do with `x`? – Ricardo Saporta Sep 23 '13 at 02:52
  • Oh sorry, I'm just saying that's what I do...it's an alternative, but I don't have an argument for it beyond that it's no-frills and thus fairly easy to maintain. Merging is simpler for me to understand than lapply with names or whatever. Also, a data.frame is easy to read when printed. Alternately, it's pretty easy to just `read.table(text=...`, with space-separated pairs on each line, and then merge that in. Anyway, probably off-topic here. – Frank Sep 23 '13 at 02:58
  • @Frank I've never used Vectorize before & just now looking @ the documentation, could you post a small example or reference? – NiuBiBang Sep 23 '13 at 03:00
  • @DaNiu, there was a question on SO some while back on how to vectorize which offered a good explanation of the function – Ricardo Saporta Sep 23 '13 at 03:08
  • 1
    @DaNiu I've edited a reply into this answer, but Ricardo can remove it if desired. – Frank Sep 23 '13 at 03:10
  • nah, @Frank, thats great – Ricardo Saporta Sep 23 '13 at 04:16