如何使用ddply或dplyr来评估具有针对数据帧的非向量输入的多变量函数?

时间:2015-06-23 20:14:22

标签: r plyr

我正在尝试在使用展开网格创建的数据集中的一系列点上运行数值模拟。如果可能的话,我想使用plyrdplyr。但是,我不懂语法。

下面的代码是否存在小扰动,将x和y的值分别应用于f?

f <- function(x, y) {
    A <- data_frame(a = x*runif(100) - y)
    B <- data_frame(b = A$a - rnorm(100)*y)
    sum(A$a) - sum(B$b)
}

X <- expand.grid(x = 1:10, y = 2:8)
X %>% mutate(z = f(x, y))

我原本希望ddply可以让这更容易。

编辑:这似乎符合预期:

 X %>% ddply(.(x, y), transform, z = f(x, y))

1 个答案:

答案 0 :(得分:1)

让我们在没有data_frame调用的情况下重写你的函数来做同样的事情,只需使用向量就会更快:

f <- function(x, y) {
    a = x * runif(100) - y
    b = a - rnorm(100) * y
    sum(a) - sum(b)
}

由于您希望将其应用于每一行,您可以使用plyrdplyr执行此操作。这些工具是为&#34; split-apply-combine&#34;制作的,您可以将数据框拆分成碎片,对每个碎片做一些事情,然后将它们放回原处。您希望每个行都有一些内容,因此我们将xy都设置为分组变量,这是有效的,因为x和y的组合唯一地定义了一行:

# plyr
ddply(X, .(x, y), plyr::mutate, z = f(x, y))

# dplyr
group_by(X, x, y) %>% dplyr::mutate(z = f(x, y))

对于plyrdplyr,都使用了mutate函数,因为您希望将列添加到现有数据框中,并保持相同的行数。要使用的另一个常用函数是summarize,当您要将具有多行的组压缩到单个汇总行中时,可以使用该函数。 mutatebase::transform非常相似。

使用plyr进行数据框操作确实没有优势,dplyr速度更快,大多数人认为更容易理解。当你有更复杂的操作并使用组而不是单独的行时,它真的很闪耀。对于单个行,基函数mapply运行良好:

X$z = mapply(f, X$x, X$y)

(感谢评论中的@jeremycg)。您可以使用dplyr,但在这种情况下没有理由这样做。