![](/img/trans.png)
[英]How do I pass multiple columns from a dataframe as individual arguments to a custom function in R
[英]How to add multiple columns to a dataframe from a custom function in R
我創建了一個代碼,它將采用輸入向量,根據輸入創建數據幀,優化一些值並返回其中一些值。 我現在把它變成一個函數,它將在輸入數據幀上按行計算。 下面是我想要實現的最小工作示例(我的實際功能在這里分享的時間太長了!):
# Randomly generated dataframe
df <- data.frame(a = rnorm(10, 0, 1), x = rnorm(10, 1, 3), y = rnorm(10, 2, 3))
# Function that takes multiple arguments and returns multiple values in a list
zsummary <- function(x, y) {
if (y < 0) return(list(NA, NA))
z = rnorm(10, x, abs(y))
return(list(mean(z), sd(z)))
}
# Example of something that works using dplyr
# However, this results in a lot of function calls...
# especially if there were a lot of columns in the list...
library(dplyr)
df %>% rowwise() %>%
mutate(mean = zsummary(x,y)[[1]], sd = zsummary(x,y)[[1]])
如您所見,我不能將單獨的函數應用於每個新的df$mean
和dfsd
列,因為它們依賴於只能生成一次的z
向量。 我已經看過SO,但我還沒有找到答案。 我認為解決方案是使用其中一個apply
函數而不是dplyr
,但我老實說從來沒有完全理解apply
函數。 我也不會喜歡使用的解決方案for
以循環rbind
正如我在以前的項目嘗試這樣做,對於大dataframes就變得非常慢!
我們可以使用mapply
。 由於zsummary
有兩個參數, mapply
將是一個選項,因為它采用'x'和'y'的相應元素來應用zsummary
。
t(mapply(zsummary, df$x, df$y))
我們也可以稍微更改函數並使用dplyr
獲取輸出
zsummary <- function(x, y) {
if (y < 0) return(data.frame(mean = NA, sd = NA))
z = rnorm(10, x, abs(y))
data.frame(mean = mean(z), sd = sd(z))
}
df %>%
rowwise() %>%
do(data.frame(., zsummary(.$x, .$y)))
或者正如我們在評論中討論的那樣,不是讓函數采用多個參數,而是使用單個參數並使用apply
with MARGIN=1
將其應用於每一行。
zsummary2 <- function(v1){
if(v1[2] < 0) return(c(mean = NA, sd = NA))
z <- rnorm(10, v1[1], abs(v1[2]))
c(mean = mean(v1), sd= sd(v1))
}
t(apply(df[-1], 1, zsummary2))
# mean sd
# [1,] 1.403066 0.8757504
# [2,] 5.058188 5.1401507
# [3,] 4.288365 1.4194393
# [4,] 1.932829 6.7587054
# [5,] -1.864236 3.7587462
# [6,] NA NA
# [7,] 3.328629 1.3711950
# [8,] -2.347699 5.0449958
# [9,] 2.936615 1.7332283
#[10,] NA NA
注意:每次運行的值都不同,因為我們沒有為rnorm
設置任何種子。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.