3

我有一个名为 data 的数据框。我正在使用名为 KEY 的属性使用 split 函数拆分数据。

data <- split(data, data$KEY);   

通过 KEY 拆分数据框后,我们得到的是各个公司的数据。数据框数据包含宇宙中所有公司的数据。拆分后,每个单独的拆分都有两列,年份和销售额。对于每个拆分,我必须计算每年对应的增量销售额。例如,如果我们有数据 2002 - 10, 2003 - 12, 2004 - 15, 2005 - 20。我有兴趣得到的是 2003-2, 2004 -3, 2005 - 5,对于每个拆分。我编写了一个名为 mod_sale 的函数来执行上述工作:

data[with(data, order(year)),];
sale_data <- diff(data$SALE);
data <- data[-1,];
data$SALE <- sale_data;
return(data)

目前,我正在使用 for 循环:

for(key in names(data)){
a <- try(mod_sale(data[[key]]))
if(class(a) == "try-error") next;
mod_data <- rbind(mod_data,a)};

我认为有某种方法,我可以使用 sapply (也可能是 plyr)。有人可以帮我改进这个 R 代码吗?不确定 sapply 代码会如何运行。

sapply(data, mod_sale)

任何帮助,将不胜感激。谢谢。

编辑:

这是一个数据示例:

a <- data.frame();
key <- c(1,1,1,1,2,2,2,2,2,3,3,3);
sales <- c(12,12,15,8,3,6,3,9,9,12,3,7);
year <- c(2002,2003,2004,2005,2001,2002,2003,2004,2005,2003,2004,2005);
ovar <- runif(12,5.0,7.5);
a <- data.frame(key,sales,year,ovar)

在生成的 data.frame 中,我期待的是增量销售而不是实际销售。显然,我们会为 3 个 key 丢失 3 个数据点;每个起始年一个,因为我们正在考虑差异。因此,结果 data.frame 中将少三行,其中包含 key、diff(sales)、year 和 ovar 列。

4

3 回答 3

2

这就是我会做的:

a$diffsales <- ave( a$sales, a$key, FUN=function(x) c(NA, diff(x) ) )
a
   key sales year     ovar diffsales
1    1    12 2002 6.845177        NA
2    1    12 2003 6.328153         0
3    1    15 2004 6.872669         3
4    1     8 2005 6.098920        -7
5    2     3 2001 7.154824        NA
6    2     6 2002 6.110810         3
7    2     3 2003 5.906624        -3
8    2     9 2004 5.214369         6
9    2     9 2005 5.818218         0
10   3    12 2003 5.354354        NA
11   3     3 2004 6.728992        -9
12   3     7 2005 7.412213         4
于 2013-11-08T22:29:21.690 回答
1

使用data.table

library(data.table)
dt = data.table(a)

dt[, sale_diff := c(NA, diff(sales)), by = key]
dt
#    key sales year     ovar sale_diff
# 1:   1    12 2002 7.416857        NA
# 2:   1    12 2003 5.625818         0
# 3:   1    15 2004 5.018934         3
# 4:   1     8 2005 6.671986        -7
# 5:   2     3 2001 6.242739        NA
# 6:   2     6 2002 6.297763         3
# 7:   2     3 2003 6.482124        -3
# 8:   2     9 2004 6.724256         6
# 9:   2     9 2005 5.071265         0
#10:   3    12 2003 6.136681        NA
#11:   3     3 2004 6.974392        -9
#12:   3     7 2005 6.517553         4
于 2013-11-08T22:31:43.643 回答
1

我很欣赏尝试展示您尝试过的内容。谢谢你。

以后尽量提供一个小例子,像这样:

df <- data.frame(year = 2001:2010,
                 sale = sample(20,10))

df <- rbind(df,df,df)
df$key <- rep(letters[1:3],each = 10)

这使您的数据看起来更清晰,并且让人们容易回答。您为我们做的越容易,您将获得更快+更好的答案。

我建议在拆分之前进行排序:

#Sort first (already sorted, but you get the idea)
df <- df[order(df$key,df$year),]
df_split <- split(df,df$key)

您实际上并不想使用sapply. (试试看。)你只想要lapply

out <- lapply(df_split,function(x) {x$sale_diff <- c(NA,diff(x$sale)); x[-1,]})

您可以使用以下方法再次将它们放在一起:

do.call(rbind,out)

你是对的,plyr或者data.table也可以这样做。我会把这些例子留给其他人。

于 2013-11-08T21:48:34.623 回答