所以我有一个数据框,我想对其进行转换和总结。 当前看起来像这样
样品数据
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
答案 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()
将数据重整为“长”格式,以便每个日期-水果-参数组合都有一个唯一的行。 (此处的“参数”是“费用”或“计数”。)
不过,根据您的预期输出,也许更自然的数据视图是将每个唯一的日期-水果组合作为单独的行,但分别为cost
和count
设置列。通过separate()
和spread()
函数很容易做到这一点。 separate()
(以及gather()
和spread()
)来自tidyr
,而不是dplyr
,但是这些包经常一起使用。首先,separate()
将column
列转换为两列fruit
和parameter
。然后,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
。