【问题标题】:Scale relative to a value in each group (via dplyr)相对于每组中的值缩放(通过 dplyr)
【发布时间】:2014-11-25 01:42:50
【问题描述】:

我有一组时间序列,我想在特定间隔内相对于它们的值对它们中的每一个进行缩放。这样一来,每个系列在那时都会处于 1.0 并按比例变化。

我不知道如何用 dplyr 做到这一点。

这是一个使用 for 循环的工作示例:

library(dplyr)

data = expand.grid(
  category = LETTERS[1:3],
  year = 2000:2005)
data$value = runif(nrow(data))

# the first time point in the series
baseYear = 2002

# for each category, divide all the values by the category's value in the base year
for(category in as.character(levels(factor(data$category)))) {
  data[data$category == category,]$value = data[data$category == category,]$value / data[data$category == category & data$year == baseYear,]$value[[1]]
}

编辑:修改了问题,使基准时间点不可索引。有时“时间”列实际上是一个因素,不一定是序数。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    此解决方案与@thelatemail 非常相似,但我认为它足够不同,值得自己回答,因为它根据条件选择索引:

    data %>%
        group_by(category) %>%
        mutate(value = value/value[year == baseYear])
    
    #   category  year      value
    #...     ...   ...       ...
    #7         A  2002 1.00000000
    #8         B  2002 1.00000000
    #9         C  2002 1.00000000
    #10        A  2003 0.86462789
    #11        B  2003 1.07217943
    #12        C  2003 0.82209897
    

    (数据输出已被截断。要复制这些结果,set.seed(123) 在创建 data 时。)

    【讨论】:

      【解决方案2】:

      在 dplyr 中使用 first,确保使用 order_by

      data %>% 
        group_by(category) %>% 
        mutate(value = value / first(value, order_by = year))
      

      【讨论】:

      • 谢谢!如果我想按年中位数进行扩展,或者在索引不起作用的情况下怎么办?
      • mutate(valute = value/median(value)) 使用group_by 选择中位数应该被接管的子集。
      • 这就是媒体价值。我在问如果它按中间年份(或特定年份)的值进行缩放会怎样。
      【解决方案3】:

      类似这样的:

      data %>% 
        group_by(category) %>% 
        mutate(value=value/value[1]) %>%
        arrange(category,year)
      

      结果:

      #   category year     value
      #1         A 2000 1.0000000
      #2         A 2001 0.2882984
      #3         A 2002 1.5224308
      #4         A 2003 0.8369343
      #5         A 2004 2.0868684
      #6         A 2005 0.2196814
      #7         B 2000 1.0000000
      #8         B 2001 0.5952027
      

      【讨论】:

      • 另一种方法是使用firstorder_by。使用order_by,最小年份应位于每个类别的第一行。 mutate(group_by(data, category), out = order_by(year, value / first(value))) %>% arrange(category)
      • 谢谢!如果我想按中位年份进行扩展,而索引不起作用怎么办?
      • @sharoz 你是说mutate(value=value/median(year))
      • @DavidRobinson 我的意思是中间年份的值
      • @sharoz:啊,明白了。您可以使用approx 函数,该函数基于另一个向量(线性)插值。试试data %>% group_by(category) %>% arrange(category, year) %>% mutate(value = value / approx(year, value, median(year))$y)
      猜你喜欢
      • 1970-01-01
      • 2022-06-11
      • 2011-02-22
      • 2019-03-31
      • 2017-02-11
      • 2020-07-16
      • 1970-01-01
      • 2021-07-09
      • 2011-09-12
      相关资源
      最近更新 更多