簡體   English   中英

在 R 中,將列表中的多個分布函數傳遞給新的 function

[英]In R, pass multiple distribution functions in a list, to a new function

我有多個分布函數,可以說:

A <- function(x)dnorm(x, mean = 3, sd = 1)
B <- function(x)dnorm(x, mean = 6, sd = 1)
C <- function(x)dnorm(x, mean = 2, sd = 2)

我想創建一個新的比例分布 function。 對於上面的三個函數,使用pdqr package,我可以這樣寫:

x <- seq(1, 10, by = 0.1)

P <- data.frame(x) %>%
  mutate(A = A(x),
         B = B(x),
         C = C(x)) %>%
  mutate(y = A * B * C) %>%
  pdqr::new_d(type = "continuous")

這會根據 A、B 和 C 生成如下所示的比例分布 P。 在此處輸入圖像描述

現在,由於創建基於 2 到 10 個其他分布的新分布函數很麻煩,我想創建一個 function,它采用分布列表來創建新的比例分布 function。 理想情況下,它將采用以下輸入: P <- foo(c(A, B, C))

但是,我似乎沒有比這更進一步的了:

foo <- function(list){
  #set x values
  x <- seq(1, 10, by = 0.1)
  #create new function
  data.frame(x) %>%
    for(i in list){
      mutate(i = i(x))%>%
        mutate(y = i * i) %>%
        new_d(type = "continuous")
    }
  
}

這顯然行不通。 問題是雙重的:如何將列表中的函數傳遞給:

  1. 創建新向量來計算每個x的概率
  2. 創建一個乘以步驟 1 中生成的值的y

%>% pipe 中使用for循環的一些問題:

  1. 數據無處可去,您需要將循環包裝在{ -braces 中並使用. 數據占位符。
  2. for循環中,您正在計算然后丟棄結果。 R 並不神奇地知道您打算使用它什么。

坦率地說,如果沒有 dplyr/magrittr,您的 function 可能會更清晰:

foo <- function(x, ...) {
  y <- 1L # identity
  for (fun in list(...)) y <- y * fun(x)
  y
}

foo(x, A, B, C)
#  [1] 1.413004e-08 2.884836e-08 5.758736e-08 1.123988e-07 2.144986e-07 4.002355e-07 7.301887e-07 1.302516e-06 2.271744e-06
# [10] 3.874040e-06 6.459473e-06 1.053073e-05 1.678604e-05 2.616173e-05 3.986695e-05 5.940021e-05 8.653490e-05 1.232602e-04
# [19] 1.716655e-04 2.337607e-04 3.112349e-04 4.051664e-04 5.157116e-04 6.418135e-04 7.809786e-04 9.291756e-04 1.080898e-03
# [28] 1.229420e-03 1.367238e-03 1.486676e-03 1.580581e-03 1.643031e-03 1.669948e-03 1.659543e-03 1.612511e-03 1.531952e-03
# [37] 1.423036e-03 1.292454e-03 1.147737e-03 9.965485e-04 8.460240e-04 7.022558e-04 5.699495e-04 4.522783e-04 3.509163e-04
# [46] 2.662133e-04 1.974623e-04 1.432080e-04 1.015496e-04 7.040736e-05 4.772941e-05 3.163607e-05 2.050252e-05 1.299153e-05
# [55] 8.048999e-06 4.875866e-06 2.887953e-06 1.672464e-06 9.470038e-07 5.242942e-07 2.838094e-07 1.502128e-07 7.773480e-08
# [64] 3.933258e-08 1.945887e-08 9.412636e-09 4.451776e-09 2.058655e-09 9.308129e-10 4.114997e-10 1.778710e-10 7.517422e-11
# [73] 3.106427e-11 1.255110e-11 4.958277e-12 1.915174e-12 7.232924e-13 2.670841e-13 9.642964e-14 3.404093e-14 1.174953e-14
# [82] 3.965229e-15 1.308411e-15 4.221324e-16 1.331623e-16 4.107168e-17 1.238603e-17 3.652160e-18 1.052922e-18 2.968046e-19
# [91] 8.180384e-20

可以將其存儲回您的框架中。 如果你想在%>% -管道中使用它,那么

tibble(myx = x) %>%
  mutate(y = foo(myx, A, B, C))
# # A tibble: 91 x 2
#      myx            y
#    <dbl>        <dbl>
#  1   1   0.0000000141
#  2   1.1 0.0000000288
#  3   1.2 0.0000000576
#  4   1.3 0.000000112 
#  5   1.4 0.000000214 
#  6   1.5 0.000000400 
#  7   1.6 0.000000730 
#  8   1.7 0.00000130  
#  9   1.8 0.00000227  
# 10   1.9 0.00000387  
# # ... with 81 more rows

但是,從您的 plot 看來,您似乎還想保留所有中間列,可以通過以下方式完成:

foo <- function(x, ...) {
  funs <- list(...)
  if (is.null(names(funs))) names(funs) <- paste0("V", seq_along(funs))
  out <- lapply(funs, function(f) f(x))
  out$y <- do.call(mapply, c(list(FUN = prod), out))
  data.frame(out)
}
tibble(myx = x) %>%
  mutate(foo(myx, A1=A, B1=B, C1=C))
# # A tibble: 91 x 5
#      myx     A1         B1    C1            y
#    <dbl>  <dbl>      <dbl> <dbl>        <dbl>
#  1   1   0.0540 0.00000149 0.176 0.0000000141
#  2   1.1 0.0656 0.00000244 0.180 0.0000000288
#  3   1.2 0.0790 0.00000396 0.184 0.0000000576
#  4   1.3 0.0940 0.00000637 0.188 0.000000112 
#  5   1.4 0.111  0.0000101  0.191 0.000000214 
#  6   1.5 0.130  0.0000160  0.193 0.000000400 
#  7   1.6 0.150  0.0000249  0.196 0.000000730 
#  8   1.7 0.171  0.0000385  0.197 0.00000130  
#  9   1.8 0.194  0.0000589  0.198 0.00000227  
# 10   1.9 0.218  0.0000893  0.199 0.00000387  
# # ... with 81 more rows

### or without A1= names:
tibble(myx = x) %>%
  mutate(foo(myx, A, B, C))
# # A tibble: 91 x 5
#      myx     V1         V2    V3            y
#    <dbl>  <dbl>      <dbl> <dbl>        <dbl>
#  1   1   0.0540 0.00000149 0.176 0.0000000141
#  ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM