簡體   English   中英

通過使用 tidyverse 更改參數並應用系列函數來調用相同的 function

[英]Call the same function by varying parameters with tidyverse and apply family functions

這是我在 Stack Overflow 上的第一個問題,所以如果我不夠清楚,我提前道歉。 我搜索了類似的問題,但我沒有找到任何東西(我可能搜索的不夠多!)

給定一個由四組點組成的data.frame (或data.tabletibble ),分為兩組:

df_points <- tibble(
    x = c(rnorm(10000, mean = 0), rnorm(10000, mean = 1), 
          rnorm(10000, mean = 0), rnorm(10000, mean = 4)), 
    dist = c(rep("d1", 10000), rep("d2", 10000), 
             rep("d1", 10000), rep("d2", 10000)), 
    overlap = c(rep("o1", 20000), rep("o2", 20000))
)

我的目標是應用density function,對"o1""o2"組使用不同的bwfromto值。

我想用tidyverseR-base以優雅的方式解決這個問題 - data.table方法( apply家庭功能)。

現在我已經設法通過tidyverse做到這一點:

  1. 我定義了一個common_dens function 應用density並返回分布的xy的小標題

    common_dens <- function(df, Bw, lower, upper) { d <- density(df, n = 2048, bw = Bw, from = lower, to = upper) df_d <- tibble(x = d$x, y = d$y) return(df_d) }
  2. 假設upper、lower和bws的值如下:

     lower <- c(-5.050, -4.705) upper <- c(6.445, 9.070) bws <- c(0.1427, 0.1417)

    我通過以下for循環獲得了所需的 dataframe:

     df_dens <- NULL for (i in 1:2) { df_t <- df_points %>% filter(overlap == unique(df_points$overlap)[[i]]) %>% group_by(dist, overlap) %>% summarise(common_dens(x, bws[i], lower[i], upper[i])) df_dens <- rbind(df_dens, df_t) }

有什么辦法可以去掉for循環?

有沒有辦法對apply系列功能和data.table做同樣的事情?

謝謝你的幫助!

purrr::pmap function 允許您將任意數量的參數連續應用於 function。 pmap_dfr返回按行綁定的 data.frame:

考慮作為 data.frame 提供的參數:

params <- data.frame(group = c("o1","o2"), bws, lower, upper)
  group    bws  lower upper
1    o1 0.1427 -5.050 6.445
2    o2 0.1417 -4.705 9.070

參數會自動分配給特殊符號..1..2等:

library(purrr)
pmap_dfr(params, ~ df_points %>%
           filter(overlap == ..1) %>%
           group_by(dist, overlap) %>%
           summarise(common_dens(x,Bw = ..2, lower = ..3, upper = ..4)))

哪個..#是哪個可能會讓人感到困惑,所以一個技巧是使用with(list(...), )

pmap_dfr(params, ~ with(list(...), df_points %>%
           filter(overlap == group) %>% 
           group_by(dist, overlap) %>% 
           summarise(common_dens(x,Bw = bws, lower = lower, upper = upper))))

您當然可以對基礎 R 執行相同的操作:

apply(params, 1, function(y){ df_points %>%
        filter(overlap == y[1]) %>% 
        group_by(dist, overlap) %>% 
        summarise(common_dens(x, Bw = as.numeric(y[2]), lower = as.numeric(y[2]),
                              upper = as.numeric(y[4])))}) %>%
   bind_rows()

但是,由於apply會轉換類型,因此您需要使用as.numeric

暫無
暫無

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

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