(以下场景简化了我的实际情况)
我的数据来自村庄,我想通过一个村庄变量来总结一个结果变量。
> 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
Run Code Online (Sandbox Code Playgroud)
例如,我想计算Y仅Z==z由村庄使用的平均值。在这种情况下,我希望村庄“a”为 (500 + 400)/2 = 450,村庄“b”为 700。
请注意,实际情况更复杂,我不能直接使用这个答案,但重点是我需要将分组的 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))
}
Run Code Online (Sandbox Code Playgroud)
但是,我发现.传递整个 tibble 并且上面的代码为所有组返回相同的值。
您可以简化一些事情。一是在您的函数中:由于您正在z向函数传递一个值,因此您不需要使用get("z"). 你有一个z你传入的全局环境;或者,更安全的是,将 z 值分配给具有其他名称的变量,这样就不会遇到范围问题,并将其传递给函数。在本例中,我将其称为z_val.
library(tidyverse)\n\nz_val <- 1\n\nY_hat_village2 <- function(data, z) {\n data_z <- data %>% filter(Z == z)\n return(mean(data_z$Y))\n}\nRun Code Online (Sandbox Code Playgroud)\n\n您可以使用 对每个组进行函数调用do,这将为您提供一个列表列,然后取消该列的嵌套。再次注意,我将变量传递z_val给参数z。
df %>%\n group_by(village) %>%\n do(y_hat = Y_hat_village2(., z = z_val)) %>%\n unnest()\n#> # A tibble: 2 x 2\n#> village y_hat\n#> <chr> <dbl>\n#> 1 a 450\n#> 2 b 700\nRun Code Online (Sandbox Code Playgroud)\n\n然而,do已被弃用purrr::map,取而代之的是 ,我仍然无法掌握窍门。在这种情况下,您可以分组和嵌套,这会给出一列名为 的数据框data,然后映射该列并再次提供z = z_val。当您取消y_hat嵌套列时,您仍然拥有作为嵌套列的原始数据,因为您仍然希望访问其余列。
df %>%\n group_by(village) %>%\n nest() %>%\n mutate(y_hat = map(data, ~Y_hat_village2(., z = z_val))) %>%\n unnest(y_hat)\n#> # A tibble: 2 x 3\n#> village data y_hat\n#> <chr> <list> <dbl>\n#> 1 a <tibble [3 \xc3\x97 3]> 450\n#> 2 b <tibble [2 \xc3\x97 3]> 700\nRun Code Online (Sandbox Code Playgroud)\n\n为了检查一切是否正常,我还检查了z = 01. 范围问题,以及 2. z 的其他值是否有效。
df %>%\n group_by(village) %>%\n nest() %>%\n mutate(y_hat = map(data, ~Y_hat_village2(., z = 0))) %>%\n unnest(y_hat)\n#> # A tibble: 2 x 3\n#> village data y_hat\n#> <chr> <list> <dbl>\n#> 1 a <tibble [3 \xc3\x97 3]> 800\n#> 2 b <tibble [2 \xc3\x97 3]> 300\nRun Code Online (Sandbox Code Playgroud)\n