【问题标题】:melt dataframe and group by using dplyr calculations in R通过在 R 中使用 dplyr 计算来融化数据框和分组
【发布时间】:2019-10-22 12:57:47
【问题描述】:

我的样本数据 `

structure(list(state = c("AP", "AP"), district = c("krishna", 
"guntur"), rate = c(170104.5156, 1343.78134), growth_in_2016 = c(0.3844595, 
0.3678), growth_in_2017 = c(0.444595, 0.8445), growth_in_2018 = c(0.323699, 
0.36213), growth_in_2019 = c(0.5777, 0.35256), growth_in_2020 = c(0.2669097, 
0.9097)), class = c("data.table", "data.frame"), row.names = c(NA,-2L), .internal.selfref = <pointer: 0x00000000026c1ef0>)

`

我正在尝试按州和地区分组,然后计算每年的月增长率。​​p>

每月计算公式为:(1+rates*growth_in_year)^(1/12) -1 有错请指正

`

state     district     date        rates
AP        krishna    2016-12-31       x
AP        krishna    2017-01-31       y
AP        krishna    2017-02-28       z
AP        krishna    2017-03-30       a
AP        krishna    2017-04-31       b
AP        krishna    2017-05-30       c
AP        krishna    2017-06-31       d

对于其他地区也是如此。 每个地区的费率必须每年递增。 我想要日期格式而不是年份格式。

【问题讨论】:

  • 为什么所有growth.. 列的名称相同但值不同?
  • @RonakShah 因为它是基于州级别的,所以我将它们设置为地区级别,即增长与州级别相同,并且地区的 base_point(rates) 不同。
  • 再次检查您的样本数据。您有五列同名“growth_in_2016”,因此对于每一行,单个变量有四个(有一个重复)值。
  • @heds1,这就是我的数据。但我将通过更改growth_rate 来编辑我的帖子以查看差异。
  • 所以对于每个statedistrict,您希望每年有12 行,而新计算的每月数据与全年相同?在共享的示例中,因为您有 5 年的数据,每行将扩展为 12 X 5 = 60 行?

标签: r dataframe dplyr plyr reshape2


【解决方案1】:

我们可以先将gather数据转长格式,然后group_bystatedistrictyear,找到新的每月rate,从列名中提取年份并创建@987654327 @ 代表全年月份的最后一天,最后计算 rate 的累积总和,得到每个月的增量值。

library(dplyr)
library(tidyr)

df %>%
  gather(key, value, -(1:3)) %>%
  group_by(state, district, key) %>%
  mutate(rate = (1 + rate * value)^(1/12) - 1, 
         year = sub(".*(\\d{4})", "\\1", key),
        dates = list(seq(as.Date(paste0(year, "-01-01")),
                     as.Date(paste0(year, "-12-01")), by = "month")- 1)) %>%
  unnest() %>% 
  mutate(rate = cumsum(rate)) %>%
  select(-year)


#  state district  rate key            value dates     
#  <chr> <chr>    <dbl> <chr>          <dbl> <date>    
# 1 AP    krishna   1.52 growth_in_2016 0.384 2015-12-31
# 2 AP    krishna   3.04 growth_in_2016 0.384 2016-01-31
# 3 AP    krishna   4.56 growth_in_2016 0.384 2016-02-29
# 4 AP    krishna   6.08 growth_in_2016 0.384 2016-03-31
# 5 AP    krishna   7.60 growth_in_2016 0.384 2016-04-30
# 6 AP    krishna   9.12 growth_in_2016 0.384 2016-05-31
# 7 AP    krishna  10.6  growth_in_2016 0.384 2016-06-30
# 8 AP    krishna  12.2  growth_in_2016 0.384 2016-07-31
# 9 AP    krishna  13.7  growth_in_2016 0.384 2016-08-31
#10 AP    krishna  15.2  growth_in_2016 0.384 2016-09-30
# … with 110 more rows

数据

df <- structure(list(state = c("AP", "AP"), district = c("krishna", 
"guntur"), rate = c(170104.5156, 1343.78134), growth_in_2016 = c(0.3844595, 
0.3678), growth_in_2017 = c(0.444595, 0.8445), growth_in_2018 = c(0.323699, 
0.36213), growth_in_2019 = c(0.5777, 0.35256), growth_in_2020 = c(0.2669097, 
0.9097)), class = c("data.table", "data.frame"), row.names = c(NA, -2L))

【讨论】:

  • 尝试时出现以下错误:Error in seq.Date(as.Date(paste0(year, "-01-01")), as.Date(paste0(year, : 'from' must be of length 1
  • @Lalitha 似乎对您共享的数据有用。您是否有任何额外的列未显示在数据中?您可以只选择并运行显示的相同列并再次运行吗?
  • 我正在使用相同的数据。你能给我任何线索吗。
  • @Lalitha 我用我正在使用的数据更新了帖子。你能用那个试试吗?
【解决方案2】:

我们可以用mutate_at对'growth'列做速率计算,然后gather变成'long'格式,去掉'date'的子串,按'state','district'分组,得到'value' 列的cumsum

library(tidyverse)
out <- df %>%
       mutate_at(vars(starts_with('growth')), list(~ (1 + rate * .)^(1/12) - 1)) %>% 
       gather(date, value, matches("growth")) %>%
       mutate(date = str_remove(date, ".*_")) %>%
       group_by(state, district) %>% 
       mutate(value = cumsum(value))
out %>%
  filter(district == "krishna")
# A tibble: 5 x 5
# Groups:   state, district [1]
#  state district    rate date  value
#  <chr> <chr>      <dbl> <chr> <dbl>
#1 AP    krishna  170105. 2016   1.52
#2 AP    krishna  170105. 2017   3.07
#3 AP    krishna  170105. 2018   4.55
#4 AP    krishna  170105. 2019   6.16
#5 AP    krishna  170105. 2020   7.60

【讨论】:

  • 得到了你的显示输出,但这里我们只有年份数字而不是每月预测。请帮助我。提前致谢
  • @Lalitha 请在您的帖子中填写预期输出。不清楚你想要什么
  • 编辑了我的问题。此外,我的示例输出显示我希望使用日期格式,而不是使用具有不同增长率的相同年份名称。请帮我。提前致谢
猜你喜欢
  • 1970-01-01
  • 2021-08-22
  • 2022-11-25
  • 2021-02-27
  • 1970-01-01
  • 2023-03-29
  • 2018-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多