如何在R Dataframe 中获得按行标签分组的列均值?

fzsnzjdm  于 2023-02-06  发布在  其他
关注(0)|答案(3)|浏览(132)

我有一个 Dataframe ,看起来像这样
| 水果|小行星2021|小行星2022|
| - ------|- ------|- ------|
| 苹果|十二|二十九|
| 香蕉|十一|三十一|
| 苹果|四十四|五十五|
| 橘子|三十|七十三|
| 橘子|十九|八十二|
| 香蕉|二十四|七十八|
水果的名称没有排序,所以我不能一次取n来分组,它们是随机列出的。我需要得到2021年和2022年水果的平均销量,以及苹果、橙子和香蕉的平均销量。
我的密码是

2021 <- c(mean(df$2021), sd(df$2021))
2022 <- c(mean(df$2022), sd(df$2022))
measure <- c('mean','standard deviation')

df1 <- data.table(measure,TE,TW,NC,SC,NWC)

输出如下所示:
| 措施|小行星2021|小行星2022|
| - ------|- ------|- ------|
| 均值|二十三点三|五十八|
| 标准差|十二、四|二十三点三|
但是我不确定从哪里开始按名称对行进行分组。
| 措施|小行星2021|苹果|香蕉|橘子|小行星2022|苹果|香蕉|橘子|
| - ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|- ------|
| 均值|二十三点三||||五十八||||
| 标准差|十二、四||||二十三点三||||
(with空格中的相应数字)

nkkqxpd9

nkkqxpd91#

我们可以使用

library(dplyr)
library(tidyr)
library(data.table)
library(stringr)
df1 %>%
   pivot_longer(cols = where(is.numeric), names_to = 'year') %>% 
   as.data.table %>%
   cube( .(Mean = mean(value), SD = sd(value)),
     by = c("Fruit", "year")) %>% 
   filter(!if_all(Fruit:year, is.na)) %>% 
   unite(Fruit, Fruit, year, sep = "_", na.rm = TRUE) %>% 
   filter(str_detect(Fruit, "_|\\d+")) %>% 
   data.table::transpose(make.names = "Fruit", keep.names = "Measure")
  • 输出
Measure Apples_2021 Apples_2022 Bananas_2021 Bananas_2022 Oranges_2021 Oranges_2022     2021     2022
1:    Mean    28.00000    42.00000    17.500000     54.50000    24.500000    77.500000 23.33333 58.00000
2:      SD    22.62742    18.38478     9.192388     33.23402     7.778175     6.363961 12.42041 23.57965

或者如果我们需要重复的列名

df1 %>%
    pivot_longer(cols = where(is.numeric), names_to = 'year') %>% 
   as.data.table %>%
   cube( .(Mean = mean(value), SD = sd(value)), by = c("Fruit", "year")) %>%
    mutate(Fruit = coalesce(Fruit, year)) %>%
   drop_na(year) %>%
   arrange(year, str_detect(Fruit, '\\d{4}', negate = TRUE)) %>% 
   select(-year) %>% 
   data.table::transpose(make.names = "Fruit", keep.names = "Measure")
  • 输出
Measure     2021   Apples   Bananas   Oranges     2022   Apples  Bananas   Oranges
1:    Mean 23.33333 28.00000 17.500000 24.500000 58.00000 42.00000 54.50000 77.500000
2:      SD 12.42041 22.62742  9.192388  7.778175 23.57965 18.38478 33.23402  6.363961

数据

df1 <- structure(list(Fruit = c("Apples", "Bananas", "Apples", "Oranges", 
"Oranges", "Bananas"), `2021` = c(12L, 11L, 44L, 30L, 19L, 24L
), `2022` = c(29L, 31L, 55L, 73L, 82L, 78L)),
 class = "data.frame", row.names = c(NA, 
-6L))
xam8gpfp

xam8gpfp2#

我建议这可能是更好的(从长远来看)在一个长的格式,这一总结可以开始。这只是'平均',并不难重复sd和合并这一点:

fruits <- c(NA, "Apples", "Oranges", "Bananas")
lapply(quux[,-1], function(yr) stack(sapply(fruits, function(z) mean(yr[is.na(z) | quux$Fruit %in% z])))) |>
  dplyr::bind_rows(.id = "year")
#   year   values     ind
# 1 2021 23.33333    <NA>
# 2 2021 28.00000  Apples
# 3 2021 24.50000 Oranges
# 4 2021 17.50000 Bananas
# 5 2022 58.00000    <NA>
# 6 2022 42.00000  Apples
# 7 2022 77.50000 Oranges
# 8 2022 54.50000 Bananas

其中ind中的NA表示所有果实,否则标记单个果实。

bmp9r5qi

bmp9r5qi3#

如果您将数据放入长格式,则可以使用聚合函数:

a <- aggregate(value ~ year + fruit, data=df, FUN=function(x) c(sd(x),mean(x))

其中value是一个列,你可以创建一个新的列来放置20212022下的值,然后创建一个新的列year,它相应地有20212022,在R中,长格式几乎总是要走的路。

相关问题