根据标准计算百分比变化的有效方法

时间:2016-08-15 14:37:40

标签: r

根据特定条件计算百分比变化的最有效,最快捷的方法是什么?我能想到的唯一方法是使用aggregate函数然后循环遍历每个名​​称,但我不认为它是有效的。

Dataframe 1
2015    Name
538 Johnny Appleseed
14  Johnny Appleseed
40  Johnny Appleseed
524 Johnny Appleseed
10  Sally Smith
50  Jenny Davids (There's no Jenny in 2016)


Dataframe 2
2016    Name
203 Johnny Appleseed
100 Sally Smith
50  Sally Smith
10  Sally Smith
242 Sally Smith
150 Johnny Appleseed
50  Sally Smith

[[更新]] 预期的输出示例

  • Johnny Appleseed -68.369%
  • Sally Smith 442%
  • Jenny Davids N / A

2 个答案:

答案 0 :(得分:0)

有几种方法可以完成你所追求的目标。我的首选方式是将2015年和2016年的分数合并为一个单一的长期"数据集。这样可以更轻松地在不使用循环的情况下跨不同类别聚合和转换数据。

首先让我们重命名现有列,因为数字列名称可以为您提供问题。我们还会添加一个" year"列到每个数据集。

colnames(df1) <- c('value', 'name')
colnames(df2) <- c('value', 'name')

df1$year <- 2015
df2$year <- 2016

现在可以将这些组合成一个数据集:

df3 <- rbind(df1, df2)

最后,dplyr来救援:

library(dplyr)
df.change <- group_by(df3, name, year) %>%
             summarize(value = mean(value)) %>%
             ungroup %>% group_by(name) %>%
             summarize(change = (value[year == 2016] - value[year == 2015]) / value[year == 2015])

这应该产生一个数据框,其中包含名称和百分比变化的列。

编辑:考虑缺失值的更好方法

library(dplyr)
library(tidyr)
df.change <- group_by(df3, name, year) %>%
             summarize(value = mean(value)) %>%
             ungroup %>%
             spread(year, value) %>%
             mutate(change = (`2016` - `2015`) / `2015`)

答案 1 :(得分:0)

我想这会比循环更快:

library(dplyr)

year_2015 <- c(538, 14, 40, 524, 10, 50)
name <- c("Johnny Appleseed", "Johnny Appleseed", "Johnny Appleseed", "Johnny Appleseed", "Sally Smith", "Jenny Davids")
df1 = data.frame(year_2015, name)

year_2016 <- c(203, 100, 50, 10, 242, 150, 50)
name <- c("Johnny Appleseed", "Sally Smith", "Sally Smith", "Sally Smith", "Sally Smith", "Johnny Appleseed", "Sally Smith")
df2 <- data.frame(year_2016, name)


df1 <- data.frame(summarize(group_by(df1, name),
             sum_year_2015 = sum(year_2015)))

df2 <- data.frame(summarize(group_by(df2, name),
             sum_year_2016 = sum(year_2016)))

data <- merge(df1, df2, by.x="name", by.y="name", all.x=TRUE)
data$name <- as.character(data$name)

final <- data.frame(cbind(data$name, (data$sum_year_2016 - data$sum_year_2015)/data$sum_year_2015))
names(final) <- c("name", "percentage_change")
final