r - dplyr:将分组的 tibble 传递给自定义函数

标签 r dplyr

(以下场景简化了我的实际情况)
我的数据来自村庄,我想通过村庄变量来总结结果变量。

> data
   village     A     Z      Y 
     <chr> <int> <int>   <dbl> 
 1       a     1     1   500     
 2       a     1     1   400     
 3       a     1     0   800  
 4       b     1     0   300  
 5       b     1     1   700  

例如,我想仅使用村庄的 Z==z 来计算 Y 的平均值。在本例中,我希望村庄“a”有 (500 + 400)/2 = 450,村庄“b”有 700。

请注意,实际情况比较复杂,我无法直接使用 this answer ,但重点是我需要将分组的 tibble 和全局变量 (z) 传递给我的函数

z <- 1 # z takes 0 or 1
data %>%
    group_by(village) %>% # grouping by village
    summarize(Y_village = Y_hat_village(., z)) # pass a part of tibble and a global variable

Y_hat_village <- function(data_village, z){
    # This function takes a part of tibble (`data_village`) and a variable `z`
    # Calculate the mean for a specific z in a village
    data_z <- data_village %>% filter(Z==get("z"))
    return(mean(data_z$Y))
}

但是,我发现 . 传递了整个 tibble,上面的代码为所有组返回相同的值。

最佳答案

有几件事您可以简化。一是在您的函数中:由于您向函数传递了一个值 z,因此您不需要使用 get("z")。您在传入的全局环境中有一个 z ;或者,更安全的是,将 z 值分配给具有其他名称的变量,这样就不会遇到范围问题,并将其传递给函数。在本例中,我将其称为 z_val

library(tidyverse)

z_val <- 1

Y_hat_village2 <- function(data, z) {
  data_z <- data %>% filter(Z == z)
  return(mean(data_z$Y))
}

您可以使用 do 对每个组进行函数调用,这将为您提供一个列表列,然后取消该列的嵌套。再次注意,我将变量 z_val 传递给参数 z

df %>%
  group_by(village) %>%
  do(y_hat = Y_hat_village2(., z = z_val)) %>%
  unnest()
#> # A tibble: 2 x 2
#>   village y_hat
#>   <chr>   <dbl>
#> 1 a         450
#> 2 b         700

但是,do 已被弃用,取而代之的是 purrr::map,我仍然无法掌握它。在这种情况下,您可以分组和嵌套,这会提供一列名为 data 的数据框,然后映射该列并再次提供 z = z_val。当您取消嵌套 y_hat 列时,您仍然拥有作为嵌套列的原始数据,因为您仍然希望访问其余列。

df %>%
  group_by(village) %>%
  nest() %>%
  mutate(y_hat = map(data, ~Y_hat_village2(., z = z_val))) %>%
  unnest(y_hat)
#> # A tibble: 2 x 3
#>   village data             y_hat
#>   <chr>   <list>           <dbl>
#> 1 a       <tibble [3 × 3]>   450
#> 2 b       <tibble [2 × 3]>   700

为了检查一切是否正常,我还传入了 z = 0 来检查 1. 范围问题,以及 2. z 的其他值是否有效。

df %>%
  group_by(village) %>%
  nest() %>%
  mutate(y_hat = map(data, ~Y_hat_village2(., z = 0))) %>%
  unnest(y_hat)
#> # A tibble: 2 x 3
#>   village data             y_hat
#>   <chr>   <list>           <dbl>
#> 1 a       <tibble [3 × 3]>   800
#> 2 b       <tibble [2 × 3]>   300

关于r - dplyr:将分组的 tibble 传递给自定义函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50928108/

相关文章:

r - 将NbClust()与不相似矩阵一起使用时,如何解决出现的错误?

r - 找到两个不同长度的向量之间的所有组合

r - 如何将颜色和线型映射到 ggplot2 线图中的几列

R Shiny dplyr 无功滤波器

r - 为多列单独汇总数据表

r - 使用分隔符从原始向量创建几个新向量

r - 找不到加载了dplyr的函数 “%<>%”

r - dplyr mutate 抛出 "Error: invalid subscript type ' 闭包'"错误

r - R中跨多个列的简洁子集

r - 计算大型数据集的多个固定效应