转换数据框并在R中汇总

时间:2019-07-24 15:59:51

标签: r dplyr

所以我有一个数据框,我想对其进行转换和总结。 当前看起来像这样

样品数据

sample_date<-data.frame(stringsAsFactors=FALSE,
           Date = c("2019-06-04", "2019-06-05", "2019-06-06",
                    "2019-06-07", "2019-06-08", "2019-06-09"),
           apple_cost = c(6685.5601, 17387.3072, 31587.2694, 7489.1275,
                         8490.1844, 9372.4676),
           apple_count = c(601762, 557952, 1003681, 243348, 273511, 303130),
           banana_cost = c(6685, 6685, 6685, 6685, 6685, 6685),
           banana_count = c(557952, 557952, 557952, 557952, 557952, 557952),
           orange_cost = c(6685, 6685, 6685, 6685, 6685, 6685),
           orange_count = c(1003681, 1003681, 1003681, 1003681, 1003681, 1003681)
)
        Date apple_cost apple_count banana_cost banana_count orange_cost orange_count
1 2019-06-04   6685.560      601762        6685       557952        6685      1003681
2 2019-06-05  17387.307      557952        6685       557952        6685      1003681
3 2019-06-06  31587.269     1003681        6685       557952        6685      1003681
4 2019-06-07   7489.127      243348        6685       557952        6685      1003681
5 2019-06-08   8490.184      273511        6685       557952        6685      1003681
6 2019-06-09   9372.468      303130        6685       557952        6685      1003681

我想将其转换并总结为:

预期输出

                         Type = c("apple","banana","orange"),
                         cost = c(243348,343348,443348),
                         count = c(3003681,4003681,5003681))
Type   cost   count
1  apple 243348 3003681
2 banana 343348 4003681
3 orange 443348 5003681

我确实尝试用下面的代码对其进行总结,但似乎与上面的预期输出不一样。这是我到目前为止尝试过的

我尝试过的很

current_table <- sample_date %>% 
  summarise( apple_cost = sum( apple_cost, na.rm=TRUE),
             apple_count = sum( apple_count, na.rm=TRUE),
             banana_cost = sum( banana_cost, na.rm=TRUE),
             banana_count = sum(banana_count, na.rm=TRUE),
             orange_cost = sum(orange_cost, na.rm=TRUE),
             orange_count = sum(orange_count, na.rm=TRUE))
apple_cost apple_count banana_cost banana_count orange_cost orange_count
1   81011.92     2983384       40110      3347712       40110      6022086

2 个答案:

答案 0 :(得分:2)

一个选项是

library(dplyr)# dply_0.8.3
library(tidyr) #tidyr_0.8.3.9000 
sample_date %>% 
  pivot_longer(-Date, names_to = c(".value", "fruits"), names_sep='_') %>% 
  select(-Date) %>%
  group_by(fruits) %>%
  summarise_all(sum) 

答案 1 :(得分:1)

整洁的方法

您采用的方法很冗长,并且需要很多特定于列和特定于列名称的代码。

dplyr和tidyverse的想法是使用tidy data原理,通常涉及将数据帧重塑为更长的格式,每行一条记录。

您可以使用以下代码来做到这一点:

sample_date %>% 
    gather(column, value, -Date) %>%
    separate(column, into=c('fruit', 'parameter'), sep='_') %>%
    spread(parameter, value) %>% 
    group_by(fruit) %>%
    summarize(total_cost = sum(cost),
              total_count = sum(count))

在这里,gather()将数据重整为“长”格式,以便每个日期-水果-参数组合都有一个唯一的行。 (此处的“参数”是“费用”或“计数”。)

不过,根据您的预期输出,也许更自然的数据视图是将每个唯一的日期-水果组合作为单独的行,但分别为costcount设置列。通过separate()spread()函数很容易做到这一点。 separate()(以及gather()spread())来自tidyr,而不是dplyr,但是这些包经常一起使用。首先,separate()column列转换为两列fruitparameter。然后,spread()value列用作键,将parameter列分解或“加宽”为两列。此时的结果如下所示:

Date    fruit   cost    count
2019-06-04  apple   6685.560    601762
2019-06-04  banana  6685.000    557952
2019-06-04  orange  6685.000    1003681
2019-06-05  apple   17387.307   557952
2019-06-05  banana  6685.000    557952
2019-06-05  orange  6685.000    1003681
2019-06-06  apple   31587.269   1003681
2019-06-06  banana  6685.000    557952
2019-06-06  orange  6685.000    1003681
2019-06-07  apple   7489.127    243348
2019-06-07  banana  6685.000    557952
2019-06-07  orange  6685.000    1003681
2019-06-08  apple   8490.184    273511
2019-06-08  banana  6685.000    557952
2019-06-08  orange  6685.000    1003681
2019-06-09  apple   9372.468    303130
2019-06-09  banana  6685.000    557952
2019-06-09  orange  6685.000    1003681 

您想要的输出似乎要对所有日期求和,但要分别处理每种水果类型。这就是为什么我们在group_by(fruit)之前summarize()

整个代码块的最终输出看起来像

 fruit  total_cost  total_count
apple   81011.92    2983384
banana  40110.00    3347712
orange  40110.00    6022086 

这不是您想要的格式,但对于tidyverse来说更自然。

您提供的数据与预期输出之间的差异

您期望的值似乎不会从您提供的样本数据中出现。您尝试过的代码至少给出了“正确的”数字,据我所知。例如,81011.92是所有苹果成本的总和,而不是您期望的243348

相关问题