簡體   English   中英

R:如何匯總具有不同功能的多個變量?

[英]R: How to summarize multiple variables with different functions?

我有一個數據框,其中對於每個分組變量,有兩種類型的變量:一組需要每組內的平均值,另一組需要每組內的總和。 也就是我想在應用一些鏈式函數(比如filter和select,因為原來的問題比這個更復雜)之后,對一個數據框中的兩組不同的變量應用兩個不同的summary函數。

> head(df, 10)
   group.var  x1  x2  x3  y1  y2  y3
1          1 460 477 236  65 142 384
2          1  88 336 114  93 378  52
3          1  93 290 353 384 498  43
4          1 394 105 306 172 216 267
5          1 402 145 423 425 125 322
6          2 187 473 466 279  81 484
7          2 465 373  50 422 136  78
8          2 404 455 362 205 315  12
9          2  54 202 242 348 324 275
10         2 340 380  14 442 376 491

理想情況下,我想在同一鏈中兩次使用dplyrsummarize_at函數,以在兩個不同的操作中將mean應用於變量集 1 並將sum應用於集 2,但出於明顯的原因,返回的分組 df 無法識別第二組變量。

> df1 <- df %>%
+     select(group.var, x1:xn, y1:yn) %>% # just for reference
+     filter(x2 != 20) %>% # just for reference
+     group_by(group.var) %>%
+     summarize_at(vars(x1:xn), mean) %>%
+     summarize_at(vars(y1:ym), sum)
Error in is_character(x, encoding = encoding, n = 1L) : 
  object 'y1' not found

我可以編寫兩個片段,它們執行相同的分組、選擇和過濾,但使用group.var函數進行不同的summarize_all ,然后使用group.var加入分組的 df,但我正在尋找一種更有效的方法。 我想要的最終結果是:

   group.var    x1    x2    x3    y1    y2    y3
1          1 287.4 270.6 286.4  1139  1359  1068
2          2 290.0 376.6 226.8  1696  1232  1340

任何建議,最好使用dplyrdata.table

一種方法是使用mutate ,然后使用distinct

df %>%
  select(group.var, x1:x3, y1:y3) %>% 
  filter(x2 != 20) %>% 
  group_by(group.var) %>%
  mutate_at(vars(x1:x3), mean) %>%
  mutate_at(vars(y1:y3), sum) %>%
  distinct()

輸出:

# A tibble: 2 x 7
# Groups:   group.var [2]
  group.var    x1    x2    x3    y1    y2    y3
      <int> <dbl> <dbl> <dbl> <int> <int> <int>
1         1  287.  271.  286.  1139  1359  1068
2         2  290   377.  227.  1696  1232  1340

另一種方法是對所有人進行兩個總結,然后只選擇相關的組合( x mean sum y sum ):

df %>%
  select(group.var, x1:x3, y1:y3) %>% 
  filter(x2 != 20) %>% 
  group_by(group.var) %>%
  summarise_all(funs(mean, sum)) %>%
  select(group.var, matches("x\\d_mean"), matches("y\\d_sum"))

輸出:

# A tibble: 2 x 7
  group.var x1_mean x2_mean x3_mean y1_sum y2_sum y3_sum
      <int>   <dbl>   <dbl>   <dbl>  <int>  <int>  <int>
1         1    287.    271.    286.   1139   1359   1068
2         2    290     377.    227.   1696   1232   1340

如果您對名稱中的摘要規范感到困擾,您可以在末尾添加類似%>% rename_all(function(x) gsub("_.*", "", x))

最后但並非最不重要的是,還有一種帶有purrr的方法(將提供與此處第一種方法相同的輸出):

library(tidyverse)

list(c(paste0("x", 1:3)), c(paste0("y", 1:3))) %>% 
  map2(lst(mean, sum),
       ~ df %>% 
         select(group.var, x1:x3, y1:y3) %>% 
         filter(x2 != 20) %>% 
         group_by(group.var) %>% 
         summarise_at(.x, .y)
       ) %>% 
  reduce(inner_join)

請注意,小數在上面的示例中消失了,因為這是tibble顯示它的方式,它們仍然存在,您可以在控制台中顯示它們,並在每個片段的末尾添加%>% as.data.frame()

你可以試試這個代碼:

df %>% 
group_by(group.var) %>% 
do(invoke_map_dfc(list(map_df), 
                  list(list(select(., x1:x3), mean), 
                       list(select(., y1:y3), sum))
                  ) 
   )

輸出將是

# A tibble: 2 x 7
# Groups:   group.var [2]
  group.var    x1    x2    x3    y1    y2    y3
      <int> <dbl> <dbl> <dbl> <int> <int> <int>
1         1  287.  271.  286.  1139  1359  1068
2         2  290   377.  227.  1696  1232  1340

輸入數據框:

df <- data.frame(
  id = 1:10,
  group.var = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L),
  x1 = c(460L, 88L, 93L, 394L, 402L, 187L, 465L, 404L, 54L, 340L),
  x2 = c(477L, 336L, 290L, 105L, 145L, 473L, 373L, 455L, 202L, 380L),
  x3 = c(236L, 114L, 353L, 306L, 423L, 466L, 50L, 362L, 242L, 14L),
  y1 = c(65L, 93L, 384L, 172L, 425L, 279L, 422L, 205L, 348L, 442L),
  y2 = c(142L, 378L, 498L, 216L, 125L, 81L, 136L, 315L, 324L, 376L),
  y3 = c(384L, 52L, 43L, 267L, 322L, 484L, 78L, 12L, 275L, 491L),
  stringsAsFactors = FALSE)

使用 dplyr 的新across功能可以通過這種方式完成

df1 <- df %>%
 dplyr::select(group.var, x1:x3, y1:y3) %>% # just for reference
 filter(x2 != 20) %>% # just for reference
 group_by(group.var) %>%
 summarise(across(x1:x3, mean), across(y1:y3, sum))

暫無
暫無

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

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