Reputation: 628
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.
Upvotes: 4
Views: 4552
Reputation: 55360
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)
)
}
> 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 sapply
ing 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.
Upvotes: 2