【问题标题】:Grouping data by specific observations in R按 R 中的特定观察对数据进行分组
【发布时间】:2017-06-29 03:55:14
【问题描述】:

我想创建一个从现有变量中的特定值派生的新变量。我的数据框如下所示:

year <- c("2010", "2011", "2012", "2013", "2014", "2015")
x <- c(2980, 2955, 3110, 2962, 2566, 3788)
y <- c(2453, 2919, 2930, 2864, 2873, 3031)
df <-  data.frame(year, x, y)

更具体地说,我想创建第三列,z,即xy 的比率。但是,我不想通过简单地将每一年的x 除以y 来创建这个比率。相反,我希望 2015 年(和 2014 年等)的值是前三年(即 2014 年、2013 年和 2012 年)该比率的平均值。

我查看了 Wickham 的 dplyr 包,特别是 group_by 函数,但我很难过,因为我不想按年对我的数据进行分组,而是按每年的前三年分组如上图所示(希望如此)。

【问题讨论】:

  • 计算原始比率,然后执行rolling average。如果您每年只有一个数据点,那么您根本不需要任何分组。

标签: r


【解决方案1】:

使用 dplyr 和 library(zoo):

df_fin<- df %>% mutate( z = rollmeanr(x/y,3,na.pad=TRUE))

我认为 z 列是您想要的,但最好有所需的输出。

【讨论】:

  • 这有点不正确,因为它在两端用NA 填充,导致“off by 1”错误。您希望 rollmeanr 将值与填充右侧对齐。
  • Gotitedited。哦对不起 !明白了.. 编辑了@Rich Scriven。
【解决方案2】:

使用zoo::rollmean 的答案都在正确的轨道上,但其中有几个“差一点”的错误。首先,您实际上需要zoo::rollmeanr( ..., na.pad=TRUE ),它将正确地在左侧用NA 填充输出:

> zoo::rollmeanr( df$x / df$y, 3, na.pad=TRUE )
[1]        NA        NA 1.0962018 1.0359948 0.9962648 1.0590378

第二个“off by one”错误源于此向量与其余数据的对齐。根据您的描述,您希望 2015 年的值是 2014 年、2013 年和 2012 年的平均值。但是,将上面的向量附加到您的表格将使 2015 年的值成为 2015 年、2014 年和 2013 年的平均值,而不是.要更正,您需要将输入中的最后一个值省略到滚动平均值中,并在前面加上一个 NA 来补偿:

> c( NA, zoo::rollmeanr( head(df$x / df$y,-1), 3, na.pad=TRUE ) )
[1]        NA        NA        NA 1.0962018 1.0359948 0.9962648

使用dplyr 表示法将它们放在一起:

df %>% mutate( z = c( NA, zoo::rollmeanr( head(x/y,-1), 3, na.pad=TRUE ) ) )
  year    x    y         z
1 2010 2980 2453        NA
2 2011 2955 2919        NA
3 2012 3110 2930        NA
4 2013 2962 2864 1.0962018
5 2014 2566 2873 1.0359948
6 2015 3788 3031 0.9962648

【讨论】:

  • 或者这个变化:library(zoo); transform(df, z = rollapplyr(x/y, list(-seq(3)), mean, fill = NA))
【解决方案3】:
df$z<-0
for (i in 4:6){
  df$z[i]<-mean(df$x[(i-3):(i-1)])/mean(df$y[(i-3):(i-1)])
}

一个循环,你可以得到这个:

  year    x    y        z
1 2010 2980 2453 0.000000
2 2011 2955 2919 0.000000
3 2012 3110 2930 0.000000
4 2013 2962 2864 1.089497
5 2014 2566 2873 1.036038
6 2015 3788 3031 0.996654

【讨论】:

    【解决方案4】:
    library(zoo)
    library(dplyr)
    
    df %>% mutate(z = x/y, zz = rollmean(z, 3, fill = NA)
    

    【讨论】:

    • 请清楚说明,您的答案如何解决原始问题。
    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 2012-11-12
    • 2017-06-04
    • 2016-07-04
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    相关资源
    最近更新 更多