按月差异(dplyr,R)

时间:2018-03-31 16:46:56

标签: r dplyr character apply lag

假设我有一个数据集,如下所示。该文本重复“a”到“e”,每个月都有价值。它持续时间为2016年1月至2016年3月。

date    text    value
1-16    a       13
1-16    b       2
1-16    c       3
1-16    d       1
1-16    e       20
2-16    a       30
2-16    b       50
2-16    c       20
2-16    d       10
2-16    e       40
3-16    a       34
3-16    b       3
3-16    c       2
3-16    d       1
3-16    e       4

我希望按月和文字制作一个具有差异值的列。我的意思是,17 =(30(a,2-16) - 13(a,1-16))就像这样,

date    text    value       the value that I want to have
1-16    a       13          na  
1-16    b       2           na  
1-16    c       3           na  
1-16    d       1           na  
1-16    e       20          na  
2-16    a       30  =(value(a, 2016-feb) - value(a, 2016-jan))  17
2-16    b       50  =(value(b, 2016-feb) - value(b, 2016-jan))  48
2-16    c       20  =(value(c, 2016-feb) - value(c, 2016-jan))  17
2-16    d       10  =(value(d, 2016-feb) - value(d, 2016-jan))  9
2-16    e       40  =(value(e, 2016-feb) - value(e, 2016-jan))  20
3-16    a       34  =(value(a, 2016-mar) - value(a, 2016-feb))  4
3-16    b       3   =(value(b, 2016-mar) - value(b, 2016-feb))  -47
3-16    c       2   =(value(c, 2016-mar) - value(c, 2016-feb))  -18
3-16    d       1   =(value(d, 2016-mar) - value(d, 2016-feb))  -9
3-16    e       4   =(value(e, 2016-mar) - value(e, 2016-feb))  -36

我制作了上面的数据。实际数据更长,甚至更复杂,因为它每个月包含大约2000个文本,并且数据甚至不是日期。 (它也被许多类别划分)。因此,一些手动计算值的解决方案将无效。

我尝试使用dplyr lag,例如,

df %>% group_by(date, text) %>%
arrange(date, text) %>%
mutate(diff = value - lag(value)) 

但它不起作用。我假设代码不能很好地识别文本?

最好的方法是什么?

2 个答案:

答案 0 :(得分:1)

使用dplyr ...

library(dplyr)

df %>% group_by(text) %>% mutate(newval=c(NA,diff(value)))

   date  text  value newval
   <chr> <chr> <int>  <int>
 1 1-16  a        13     NA
 2 1-16  b         2     NA
 3 1-16  c         3     NA
 4 1-16  d         1     NA
 5 1-16  e        20     NA
 6 2-16  a        30     17
 7 2-16  b        50     48
 8 2-16  c        20     17
 9 2-16  d        10      9
10 2-16  e        40     20
11 3-16  a        34      4
12 3-16  b         3    -47
13 3-16  c         2    -18
14 3-16  d         1     -9
15 3-16  e         4    -36

答案 1 :(得分:0)

或使用ave

完全在R base中
> df$newVal <- ave(df$value, df$text,  FUN=function(x) c(NA,diff(x)))
> df
   date text value newVal
1  1-16    a    13     NA
2  1-16    b     2     NA
3  1-16    c     3     NA
4  1-16    d     1     NA
5  1-16    e    20     NA
6  2-16    a    30     17
7  2-16    b    50     48
8  2-16    c    20     17
9  2-16    d    10      9
10 2-16    e    40     20
11 3-16    a    34      4
12 3-16    b     3    -47
13 3-16    c     2    -18
14 3-16    d     1     -9
15 3-16    e     4    -36

aggregate

df$newval <- c(aggregate(value ~ text, data=df, FUN=function(x) c(NA,diff(x)))[,-1])