【问题标题】:Applying a function and assigning multiple variables in a single call in R在 R 中的一次调用中应用函数并分配多个变量
【发布时间】:2014-09-16 13:43:35
【问题描述】:

需要考虑的一些示例 R 代码:

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

因此,我想通过find.key function 基于查找表(关联数组/列表)添加新变量(NewX2、Newy2)。

有什么方法可以让我的代码保持干燥吗?具体在这里:

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

我不确定sapplylapply 是否有帮助?或者像 %=% 这样的 here

我想要这样的东西......(希望这是有道理的):

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

【问题讨论】:

  • df$New &lt;- mapply(find.key, list(df$x, df$y), list(x2, y2)) 怎么样?
  • 另外,在重新编码时,更容易翻转 x2/y2 表的级别。例如:x2 &lt;- c("a"="Alpha", "b"="Beta", "c"="Other", "d"="Other"); df$newx &lt;-x2[as.character(df$x)] 那么就不需要 find.keys 函数了。
  • @MrFlick 我明白你在说什么,但想象一个更大的查找表,我可能会多次重复“其他”。这就是列表格式可能更可取的原因。
  • 如果您关心内存使用情况,这是有道理的。但是,正如我所写的那样,通过索引进行实际转换应该要快得多。但这需要测试来确认。但是对你来说更容易维护的就是更好的。

标签: r lapply sapply mapply


【解决方案1】:

[ 提取用于左侧data​​.frame 而不是$ 提取:

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

或者,如果你不喜欢写mapply,你可以使用Vectorize,它会为你创建一个基于mapply的函数来获得相同的结果:

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

【讨论】:

  • 人们使用Vectorize 不够,我不认为。我喜欢它。我已经创建了几乎所有非基元的矢量化版本。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-18
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
  • 2012-07-31
  • 2020-11-08
  • 2018-10-18
相关资源
最近更新 更多