我想使用 group_by() 命令對一堆變數運行相同的命令(基本上是一些通用的 filter()、mutate() summarise() 等)。有沒有辦法捆綁這個程序,而不必為每個單獨的變數使用一個代碼塊?我試過使用 for 回圈,不幸的是它對我不起作用。我的目標是只需為所有 group_by 變數撰寫一個代碼塊。
library(dplyr)
df <- mtcars
Test1 <- df %>%
group_by(mpg) %>%
filter(hp > 100) %>%
summarise(N = n())
Test2 <- df %>%
group_by(cyl) %>%
filter(hp > 100) %>%
summarise(N = n())
Test3 <- df %>%
group_by(disp) %>%
filter(hp > 100) %>%
summarise(N = n())
先感謝您!
uj5u.com熱心網友回復:
您可以使用 來執行此操作lapply,這將生成資料框串列。然后,您可以unlist將其應用于各個資料幀。
在我的代碼之后,您應該在全域環境中找到三個資料框,名稱分別為“Test1”、“Test2”和“Test3”。
library(dplyr)
setNames(
lapply(c("mpg", "cyl", "disp"), function(x)
mtcars %>% group_by(mtcars[x]) %>% filter(hp > 100) %>% summarize(N = n())),
c("Test1", "Test2", "Test3")
) %>% list2env(envir = .GlobalEnv)
輸出
Test1
# A tibble: 18 x 2
mpg N
<dbl> <int>
1 10.4 2
2 13.3 1
3 14.3 1
4 14.7 1
5 15 1
6 15.2 2
7 15.5 1
8 15.8 1
9 16.4 1
10 17.3 1
11 17.8 1
12 18.1 1
13 18.7 1
14 19.2 2
15 19.7 1
16 21 2
17 21.4 2
18 30.4 1
Test2
# A tibble: 3 x 2
cyl N
<dbl> <int>
1 4 2
2 6 7
3 8 14
Test3
# A tibble: 18 x 2
disp N
<dbl> <int>
1 95.1 1
2 121 1
3 145 1
4 160 2
5 168. 2
6 225 1
7 258 1
8 276. 3
9 301 1
10 304 1
11 318 1
12 350 1
13 351 1
14 360 2
15 400 1
16 440 1
17 460 1
18 472 1
uj5u.com熱心網友回復:
一種選擇是將變數名稱存盤在向量或串列中,然后使用例如lapply在我使用.data代名詞的地方回圈該串列:
library(dplyr)
df <- mtcars
var_list <- c("mpg", "cyl", "disp")
lapply(var_list, function(x) {
df %>%
group_by(.data[[x]]) %>%
filter(hp > 100) %>%
summarise(N = n())
})
#> [[1]]
#> # A tibble: 18 × 2
#> mpg N
#> <dbl> <int>
#> 1 10.4 2
#> 2 13.3 1
#> 3 14.3 1
#> 4 14.7 1
#> 5 15 1
#> 6 15.2 2
#> 7 15.5 1
#> 8 15.8 1
#> 9 16.4 1
#> 10 17.3 1
#> 11 17.8 1
#> 12 18.1 1
#> 13 18.7 1
#> 14 19.2 2
#> 15 19.7 1
#> 16 21 2
#> 17 21.4 2
#> 18 30.4 1
#>
#> [[2]]
#> # A tibble: 3 × 2
#> cyl N
#> <dbl> <int>
#> 1 4 2
#> 2 6 7
#> 3 8 14
#>
#> [[3]]
#> # A tibble: 18 × 2
#> disp N
#> <dbl> <int>
#> 1 95.1 1
#> 2 121 1
#> 3 145 1
#> 4 160 2
#> 5 168. 2
#> 6 225 1
#> 7 258 1
#> 8 276. 3
#> 9 301 1
#> 10 304 1
#> 11 318 1
#> 12 350 1
#> 13 351 1
#> 14 360 2
#> 15 400 1
#> 16 440 1
#> 17 460 1
#> 18 472 1
編輯要將結果存盤在資料框中,我將首先命名變數向量,在函式內部對分組列使用相同的名稱。即我只是使用“值”然后使用 bind_rows 將結果系結在一起,作為識別符號,我添加了變數名稱:
var_list <- c("mpg", "cyl", "disp")
names(var_list) <- var_list
lapply(var_list, function(x) {
df %>%
group_by(value = .data[[x]]) %>%
filter(hp > 100) %>%
summarise(N = n())
}) %>%
bind_rows(.id = "var")
#> # A tibble: 39 x 3
#> var value N
#> <chr> <dbl> <int>
#> 1 mpg 10.4 2
#> 2 mpg 13.3 1
#> 3 mpg 14.3 1
#> 4 mpg 14.7 1
#> 5 mpg 15 1
#> 6 mpg 15.2 2
#> 7 mpg 15.5 1
#> 8 mpg 15.8 1
#> 9 mpg 16.4 1
#> 10 mpg 17.3 1
#> # ... with 29 more rows
uj5u.com熱心網友回復:
與其他一些答案類似,但使用purrr::map()您可以創建要分組的變數向量并對其進行迭代,然后dplyr::count()簡潔地使用group_by& summarize()。這里的一個關鍵是用花括號將第一個map()陳述句括起來,以允許您將其通過管道傳遞到第一個引數以外的其他內容中。這里的另一個關鍵是,如果您想按 過濾,請在上游執行以避免重復。最后我讓每個輸出中的變數名可以組合成一個.{}.hp > 100pivot_longer()data.frame
library(tidyverse)
varz <- c("cyl", "am", "gear", "carb")
mtcars %>%
filter(hp > 100) %>%
{map(varz, \(x){count(., !!sym(x))})} %>%
map(~pivot_longer(.x, -n, names_to = "var")) %>%
bind_rows() %>%
select(var, value, n)
#> # A tibble: 14 x 3
#> var value n
#> <chr> <dbl> <int>
#> 1 cyl 4 2
#> 2 cyl 6 7
#> 3 cyl 8 14
#> 4 am 0 16
#> 5 am 1 7
#> 6 gear 3 14
#> 7 gear 4 5
#> 8 gear 5 4
#> 9 carb 1 2
#> 10 carb 2 6
#> 11 carb 3 3
#> 12 carb 4 10
#> 13 carb 6 1
#> 14 carb 8 1
由reprex 包于 2022-02-18 創建(v2.0.1)
uj5u.com熱心網友回復:
由于您已經使用了一種tidyverse方法,您可以只旋轉表格:
library(tidyverse)
df <- mtcars
df %>%
filter(hp > 100) %>%
select(mpg, cyl, hp) %>%
pivot_longer(cols = c(mpg, cyl, hp),
names_to = "var",
values_to = "value") %>%
group_by(var) %>%
summarise(N = n())
#> # A tibble: 3 × 2
#> var N
#> <chr> <int>
#> 1 cyl 23
#> 2 hp 23
#> 3 mpg 23
那能解決你的問題嗎?這樣,您可以將任何函式放在透視資料集之后,并根據需要將它們應用于所有變數。如果您希望再次將它們作為變數,您可以將其轉回。這種方法的主要優點是您永遠不會拆分資料集。但是,這也有缺點。
另一種選擇可能是使用purrr.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/427732.html
