gpt4 book ai didi

r - 使用 plyr/dplyr/purrr 将多列添加到数据框的方法

转载 作者:行者123 更新时间:2023-12-02 01:19:09 24 4
gpt4 key购买 nike

我经常需要使用自定义函数(最好使用并行化)一次性添加几列来改变数据框。以下是我已经知道如何做到这一点的方法。

设置

library(dplyr)
library(plyr)
library(purrr)
library(doMC)
registerDoMC(2)

df <- data.frame(x = rnorm(10), y = rnorm(10), z = rnorm(10))

假设我想要两个新列,foocol = x + ybarcol = (x + y) * 100,但这些实际上是在自定义函数。

方法 1:使用 rowwisemutate 单独添加列

foo <- function(x, y) return(x + y)
bar <- function(x, y) return((x + y) * 100)

df_out1 <- df %>% rowwise() %>% mutate(foocol = foo(x, y), barcol = bar(x, y))

这不是一个好的解决方案,因为它需要对每行进行两次函数调用以及两次“昂贵”的 x + y 计算。它也不是并行化的。

方法2:欺骗ddply进行行操作

df2 <- df
df2$id <- 1:nrow(df2)

df_out2 <- ddply(df2, .(id), function(r) {
foocol <- r$x + r$y
barcol <- foocol * 100
return(cbind(r, foocol, barcol))
}, .parallel = T)

在这里,我通过拆分刚刚创建的唯一 id 列来欺骗 ddply 在每一行上调用函数。但它很笨重,并且需要维护一个无用的列。

方法3:splat

foobar <- function(x, y, ...) {
foocol <- x + y
barcol <- foocol * 100
return(data.frame(x, y, ..., foocol, barcol))
}

df_out3 <- splat(foobar)(df)

我喜欢这个解决方案,因为您可以在自定义函数(如果需要,可以是匿名的)中引用 df 的列,而无需数组理解。但是,此方法不是并行化的。

方法4:by_row

df_out4 <- df %>% by_row(function(r) {
foocol <- r$x + r$y
barcol <- foocol * 100
return(data.frame(foocol = foocol, barcol = barcol))
}, .collate = "cols")

来自 purrrby_row 函数消除了对唯一 id 列的需要,但此操作不是并行化的。

方法5:pmap_df

df_out5 <- pmap_df(df, foobar)
# or equivalently...
df_out5 <- df %>% pmap_df(foobar)

这是我找到的最好的选择。 pmap 系列函数还接受匿名函数来应用于参数。不过,我相信 pmap_df 会将 df 转换为列表并返回,因此性能可能会受到影响。

这也有点烦人,我需要在函数定义中引用我计划用于计算的所有列 function(x, y, ...) 而不仅仅是 function (r) 表示行对象。

<小时/>

我是否错过了任何好的或更好的选择?我描述的方法有任何问题吗?

最佳答案

使用data.table怎么样?

library(data.table)

foo <- function(x, y) return(x + y)
bar <- function(x, y) return((x + y) * 100)

dt <- as.data.table(df)

dt[, foocol:=foo(x,y)]
dt[, barcol:=bar(x,y)]

data.table 库速度相当快,并且至少有一些 some并行化的潜力。

关于r - 使用 plyr/dplyr/purrr 将多列添加到数据框的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38403111/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com