Home > Software engineering >  improving specific code efficiency - *base R* alternative to for() loop solution
improving specific code efficiency - *base R* alternative to for() loop solution

Time:11-16

Looking for a vectorized base R solution for my own edification. I'm assigning a value to a column in a data frame based on a value in another column in the data frame.

My solution creates a named vector of possible codes, looks up the code in the original column, subsets the named list by the value found, and assigns the resulting name to the new column. I'm sure there's a way to do exactly this using the named vector I created that doesn't need a for loop; is it some version of apply?

dplyr is great and useful and I'm not looking for a solution that uses it.

# reference vector for assigning more readable text to this table
tempAssessmentCodes <- setNames(c(600,301,302,601,303,304,602,305,306,603,307,308,604,309,310,605,311,312,606,699),
                                c("base","3m","6m","6m","9m","12m","12m","15m","18m","18m","21m","24m","24m","27m","30m","30m",
                                  "33m","36m","36m","disch"))
                                    
for(i in 1:nrow(rawDisp)){
  rawDisp$assessText[i] <- names(tempAssessmentCodes)[tempAssessmentCodes==rawDisp$assessment[i]]
}

CodePudding user response:

The standard way is to use match():

rawDisp$assessText <- names(tempAssessmentCodes)[match(rawDisp$assessment, tempAssessmentCodes)]

For each y element match(x, y) will find a corresponding element index in x. Then we use the names of y for replacing values with names.

Personally, I do it the opposite way - make tempAssesmentCodes have names that correspond to old codes, and values correspond to new codes:

codes <- setNames(names(tempAssessmentCodes), tempAssessmentCodes)

Then simply select elements from the new codes using the names (old codes):

rawDisp$assessText <- codes[as.character(rawDisp$assessment)]
  • Related