将基准年索引添加到具有多个组的 R 数据框

Ant*_*tti 4 r dataframe

我有一个包含很少分组变量的年度时间序列数据框,我需要添加一个基于特定年份的索引列。

df <- data.frame(YEAR = c(2000,2001,2002,2000,2001,2002), 
                 GRP = c("A","A","A","B","B","B"),
                 VAL = sample(6))
Run Code Online (Sandbox Code Playgroud)

我想创建一个简单的变量 VAL 索引,即值除以基准年的值,比如 2000:

df$VAL.IND <- df$VAL/df$VAL[df$YEAR == 2000]
Run Code Online (Sandbox Code Playgroud)

这是不对的,因为它不尊重分组变量 GRP。我试过 plyr 但我无法让它工作。

在我的实际问题中,我有几个具有不同时间序列的分组变量,因此我正在寻找一个非常通用的解决方案。

akr*_*run 5

我们可以在分组变量 ('GRP') 内进行计算后创建 'VAL.IND'。这可以通过多种方式完成。

一种选择是data.table我们从“data.frame”(setDT(df))创建“data.table” ,按“GRP”分组,我们将“VAL”除以对应于“YEAR”值为 2000 的“VAL”。

 library(data.table)
 setDT(df)[, VAL.IND := VAL/VAL[YEAR==2000], by = GRP]
Run Code Online (Sandbox Code Playgroud)

注意:baseYEAR 对结果来说有点令人困惑。在示例中,'A' 和 'B' GRP 都具有 'YEAR' 2000。假设,如果 OP 打算使用最小 YEAR 值(考虑到它是数字列),VAL/VAL[YEAR==2000]则可以将上述代码中的VAL/VAL[which.min(YEAR)].


或者您可以使用类似的代码与dplyr. 我们按“GRP”分组并用于mutate创建“VAL.IND”

 library(dplyr)
 df %>%
    group_by(GRP) %>%
    mutate(VAL.IND = VAL/VAL[YEAR==2000])
Run Code Online (Sandbox Code Playgroud)

在这里,如果我们需要替换VAL/VAL[YEAR==2000]VAL/VAL[which.min(YEAR)]


一个base R选项split/unsplit。我们split由“GRP”列中的数据集转换data.framelist通过dataframes的,循环list用输出lapply,使用创建新列transform(或within)和转换list与加列回单data.frameunsplit

  unsplit(lapply(split(df, df$GRP), function(x) 
          transform(x, VAL.IND= VAL/VAL[YEAR==2000])), df$GRP)
Run Code Online (Sandbox Code Playgroud)

请注意,我们也可以使用do.call(rbind代替unsplit。但是,我更喜欢unsplit获得与原始数据集相同的行顺序。