简体   繁体   中英

Applying a function and assigning multiple variables in a single call in R

Some sample R code to consider:

df = data.frame(x=letters[1:4], y=letters[5:8])

find.key <- function(x, li, default=NA) {
  ret <- rep.int(default, length(x))
  for (key in names(li)) {
    ret[x %in% li[[key]]] <- key
  }
  return(ret)
}

x2 = list("Alpha" = "a", 
          "Beta"  = "b", 
          "Other" = c("c","d"))

y2 = list("Epi"    = "e", 
          "OtherY" = c("f", "g", "h"))

# This is the code in question, imagine many variables and calls to find.key()
df$NewX2 = find.key(df$x, x2)
df$Newy2 = find.key(df$y, y2)

# df
#   x y NewX2  Newy2
# 1 a e Alpha    Epi
# 2 b f  Beta OtherY
# 3 c g Other OtherY
# 4 d h Other OtherY

So the gist of this is I would like to add new variables (NewX2, Newy2) based on a lookup tables (associative arrays/list) via the find.key function .

Is there some way to keep my code DRY? specifically here:

df$NewX2 = find.key(df$x, x2)
df$Newy2 = find.key(df$y, y2)

I'm not sure sapply or lapply could help? Or perhaps something like %=% as seen here .

I'd like to something like this...(hopefully this makes sense):

c(df$NewX2, df$Newy2) = find.key(c(df$x, df$y), c(x2, y2))

Use [ extraction for the lefthand-side data.frame rather than $ extraction:

df[,c('NewX2','NewY2')] <- mapply(find.key, 
                                  list(df$x, df$y), 
                                  list(x2, y2), 
                                  SIMPLIFY=FALSE)
# df
#   x y NewX2  NewY2
# 1 a e Alpha    Epi
# 2 b f  Beta OtherY
# 3 c g Other OtherY
# 4 d h Other OtherY

Or, if you don't like writing mapply you can use Vectorize , which will create an mapply -based function for you to obtain the same result:

find.keys <- Vectorize(find.key, c("x","li"), SIMPLIFY=FALSE)
df[,c('NewX2','NewY2')] <- find.keys(list(df$x, df$y), list(x2, y2))
df
#   x y NewX2  NewY2
# 1 a e Alpha    Epi
# 2 b f  Beta OtherY
# 3 c g Other OtherY
# 4 d h Other OtherY

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM