我有一系列性能指标,并希望计算前一行在已定义分区内的百分比变化,如下所示:
index metric percent_change
A 10 0.0
A 20 1.0
A 10 -.50
A 5 -.50
B 10 0
B 5 -.50
B 10 1.00我如何在R中实现这一点?
发布于 2015-11-20 10:33:56
我们可以使用data.table。将'data.frame‘转换为'data.table’(索引),按‘setDT(df1)’分组,我们从‘data.frame’的滞后中减去‘data.table’,除以它并将结果分配(:=)到创建'percent_change‘。
library(data.table)#v1.9.6+
setDT(df1)[, percent_change := {tmp <- shift(metric, fill=metric[1L])
(metric-tmp)/tmp} , by = index]
df1
# index metric percent_change
#1: A 10 0.0
#2: A 20 1.0
#3: A 10 -0.5
#4: A 5 -0.5
#5: B 10 0.0
#6: B 5 -0.5
#7: B 10 1.0或者使用dplyr
library(dplyr)
df1 %>%
group_by(index) %>%
mutate(percent_change = (metric- lag(metric, default=metric[1L]))/lag(metric, default=metric[1L]))数据
df1 <- structure(list(index = c("A", "A", "A", "A", "B", "B", "B"),
metric = c(10L, 20L, 10L, 5L, 10L, 5L, 10L)), .Names = c("index",
"metric"),
row.names = c(NA, -7L), class = "data.frame")发布于 2015-11-20 22:35:33
另一个使用基础包的替代方案:
df1$percent_change <- unlist(
tapply(df1$metric, df1$index, function(x) c(0, x[-1]/x[1]-1) )
)或者非常类似于rawr提出的方案。
df1$percent_change <- ave(df1$metric, df1$index, FUN=function(x) c(0,x[-1]/x[1]-1))输出:
index metric percent_change
1 A 10 0.0
2 A 20 1.0
3 A 10 0.0
4 A 5 -0.5
5 B 10 0.0
6 B 5 -0.5
7 B 10 0.0https://stackoverflow.com/questions/33818011
复制相似问题