除以给定时间特定因子的值(dplyr,data.table)

除以给定时间特定因子的值(dplyr,data.table),r,dataframe,dplyr,data.table,R,Dataframe,Dplyr,Data.table,我的数据格式很长,如下所示: library(tidyverse) df <- data.frame( projection1 = c(2,4,3), projection2 = c(3,1,4), historical_data = c(2,3,4), time = c(1,2,3) ) %>% as_tibble() %>% gather(key = key, value = val, projection1:historical_data)

我的数据格式很长,如下所示:

library(tidyverse)

df <- data.frame(
  projection1 = c(2,4,3),
  projection2 = c(3,1,4),
  historical_data = c(2,3,4),
  time = c(1,2,3)
) %>% 
  as_tibble() %>% 
  gather(key = key, value = val, projection1:historical_data) %>% 
  mutate(key = key %>% factor())
# A tibble: 9 x 3
   time key               val
  <dbl> <fct>           <dbl>
1     1 projection1         2
2     2 projection1         4
3     3 projection1         3
4     1 projection2         3
5     2 projection2         1
6     3 projection2         4
7     1 historical_data     2
8     2 historical_data     3
9     3 historical_data     4
库(tidyverse)
df%
as_tible()%>%
聚集(键=键,值=值,项目1:历史数据)%>%
变异(key=key%>%factor())
然后,数据如下所示:

library(tidyverse)

df <- data.frame(
  projection1 = c(2,4,3),
  projection2 = c(3,1,4),
  historical_data = c(2,3,4),
  time = c(1,2,3)
) %>% 
  as_tibble() %>% 
  gather(key = key, value = val, projection1:historical_data) %>% 
  mutate(key = key %>% factor())
# A tibble: 9 x 3
   time key               val
  <dbl> <fct>           <dbl>
1     1 projection1         2
2     2 projection1         4
3     3 projection1         3
4     1 projection2         3
5     2 projection2         1
6     3 projection2         4
7     1 historical_data     2
8     2 historical_data     3
9     3 historical_data     4
#一个tible:9 x 3
时间键val
1项目1 2
2项目1 4
3项目1 3
4 1项目2 3
5 2项目2 1
6 3项目2 4
7 1历史数据2
8 2历史数据3
9 3历史数据4
现在,我想计算每年projection1和projection2的值相对于历史数据的相对差值。因此,我希望我的数据以这样的方式结束:

# A tibble: 9 x 4
   time key               val pct_diff
  <dbl> <fct>           <dbl>    <dbl>
1     1 projection1         2    1    
2     2 projection1         4    1.33 
3     3 projection1         3    0.75 
4     1 projection2         3    1.5  
5     2 projection2         1    0.333
6     3 projection2         4    1    
7     1 historical_data     2    1    
8     2 historical_data     3    1    
9     3 historical_data     4    1
#一个tible:9 x 4
时间键val pct_diff
1项目1 2 1
2项目1 4 1.33
3项目1 3 0.75
4 1项目2 3 1.5
5 2项目2 1 0.333
6 3项目2 4 1
7 1历史数据2 1
8 2历史数据3 1
9 3历史数据4 1
我总是通过拆分和合并得到新的看似冗余的列,这些列包含当前
dataframe
/
tibble
中已经存在的值,以进行计算。我想知道是否有一个优雅的
dplyr
或data.table解决方案?或者你可以告诉我一个已经回答过的问题。我自己也没见过


谢谢

这里有一个使用组的简单方法:

 data.frame(
  projection1 = c(2,4,3),
  projection2 = c(3,1,4),
  historical_data = c(2,3,4),
  time = c(1,2,3)
) %>% 
  as_tibble() %>% 
  gather(key = key, value = val, projection1:historical_data) %>%
  group_by(time) %>%
  mutate(pct_diff = (val  / val[key == "historical_data"]))

# Groups:   time [3]
   time key               val pct_diff
  <dbl> <chr>           <dbl>    <dbl>
1     1 projection1         2    1    
2     2 projection1         4    1.33 
3     3 projection1         3    0.75 
4     1 projection2         3    1.5  
5     2 projection2         1    0.333
6     3 projection2         4    1    
7     1 historical_data     2    1    
8     2 historical_data     3    1    
9     3 historical_data     4    1 
data.frame(
投影1=c(2,4,3),
投影2=c(3,1,4),
历史数据=c(2,3,4),
时间=c(1,2,3)
) %>% 
as_tible()%>%
聚集(键=键,值=值,项目1:历史数据)%>%
分组单位(时间)%>%
变异(pct_diff=(val/val[key==“历史数据”))
#分组:时间[3]
时间键val pct_diff
1项目1 2 1
2项目1 4 1.33
3项目1 3 0.75
4 1项目2 3 1.5
5 2项目2 1 0.333
6 3项目2 4 1
7 1历史数据2 1
8 2历史数据3 1
9 3历史数据4 1

如果您坚持认为
列是一个因素,则您必须稍微修改上述代码。

以下是一种可能的方法,使用
数据表
并使用jangorecki注释,使用
==
而不是较慢的
grep

DT[, ratio := 1][key!="historical_data", 
    ratio := DT[key=="historical_data"][.SD, on=.(time), i.val/x.val]]
或更短但可能更慢:

DT[, ratio := DT[key=="historical_data"][.SD, on=.(time), i.val/x.val]]
输出:

   time             key val     ratio
1:    1     projection1   2 1.0000000
2:    2     projection1   4 1.3333333
3:    3     projection1   3 0.7500000
4:    1     projection2   3 1.5000000
5:    2     projection2   1 0.3333333
6:    3     projection2   4 1.0000000
7:    1 historical_data   2 1.0000000
8:    2 historical_data   3 1.0000000
9:    3 historical_data   4 1.0000000
数据:

库(data.table)

DT很棒,启发了我以下几点,在这里我可以保留我的因子:
df%>%mutate(key=key%>%factor()>%fct\u relevel(“历史数据”))%%>%arrange(key)%%>%group\u by(time)%%>%mutate(pct\u diff=(val/first(val,order\u by=c(key))
grep(“历史数据”),key)
效率不高,为什么不
键==“历史数据”