我的问题涉及计算每个时期产品价格的差异。使用下面的示例数据
product = c('A','A','A','B','B','B','C','C','C')
date = as.Date(c('2016-09-12','2016-09-19', '2016-09-26','2016-09-12','2016-09-19', '2016-09-26', '2016-09-12','2016-09-19', '2016-09-26'))
price = as.numeric(c(17, 14.7, 15, 14.69, 14.64, 14.63, 13.15, 13.15, 13.15))
df <- data.frame(product, date, price)
挑战在于分组,没有分组,对外部函数的简单调用就可以解决问题。
melt(outer(df$price, df$price, "-"))
然而,将此与dplyr
中的转化功能相结合会导致出现奇怪的错误消息“错误:与STRSXP不兼容”。在线评论提示这可能是由于包中的错误造成的。
所以我想知道是否有人对替代方法有一个简洁的建议。
理想情况下,我正在寻找输出以下内容。
Var1 Var2 Date value
A A '2016-09-12' 0.00
A B '2016-09-12' 2.31
A C '2016-09-12' 3.85
B A '2016-09-12' -2.31
B B '2016-09-12' 0.00
B C '2016-09-12' 1.54
C A '2016-09-12' -3.85
C B '2016-09-12' -1.54
C C '2016-09-12' 0.00
A A '2016-09-19' 0.00
A B '2016-09-19' 0.06
A C '2016-09-19' 1.55
等等。欣赏这会留下一些冗余对,但这会让生活更轻松。
提前感谢您的关注。:)
答案 0 :(得分:3)
通常,如果数据转换不适用于mutate
/ transform
,您可以尝试do
:
> library(dplyr)
> df %>%
group_by(date) %>%
do(reshape2::melt(outer(.$price, .$price, "-")))
Source: local data frame [27 x 4]
Groups: date [3]
date Var1 Var2 value
(date) (int) (int) (dbl)
1 2016-09-12 1 1 0.00
2 2016-09-12 2 1 -2.31
3 2016-09-12 3 1 -3.85
4 2016-09-12 1 2 2.31
5 2016-09-12 2 2 0.00
6 2016-09-12 3 2 -1.54
7 2016-09-12 1 3 3.85
8 2016-09-12 2 3 1.54
9 2016-09-12 3 3 0.00
10 2016-09-19 1 1 0.00
.. ... ... ... ...
答案 1 :(得分:2)
我们可以使用data.table
library(data.table)
res <- setDT(df)[, melt(outer(price, price, "-")) , by = date]
res[, c("Var1", "Var2") := lapply(.SD, function(x)
unique(df$product)[x]),.SDcols = Var1:Var2]
head(res)
# date Var1 Var2 value
#1: 2016-09-12 A A 0.00
#2: 2016-09-12 B A -2.31
#3: 2016-09-12 C A -3.85
#4: 2016-09-12 A B 2.31
#5: 2016-09-12 B B 0.00
#6: 2016-09-12 C B -1.54
使用tidyr/dplyr
library(tidyr)
library(dplyr)
df %>%
group_by(date) %>%
expand(price, price2=price) %>%
mutate(value = price-price2)