我有一个包含少量分组变量的年度时间序列数据框,我需要添加一个基于特定年份的索引列。
df <- data.frame(YEAR = c(2000,2001,2002,2000,2001,2002),
GRP = c("A","A","A","B","B","B"),
VAL = sample(6))
我想创建一个简单的变量VAL索引,即值除以基准年的值,比如2000:
df$VAL.IND <- df$VAL/df$VAL[df$YEAR == 2000]
这是不对的,因为它不尊重分组变量GRP。我试过plyr,但我无法使它工作。
在我的实际问题中,我有几个具有不同时间序列的分组变量,因此我正在寻找一个非常通用的解决方案。
答案 0 :(得分:3)
我们可以在分组变量('GRP')中进行计算后创建'VAL.IND'。这可以通过多种方式完成。
一个选项是data.table
,我们从'data.frame'(setDT(df)
)创建'data.table',按'GRP'分组,我们将'VAL'除以'VAL'对应于2000年的'YEAR'值。
library(data.table)
setDT(df)[, VAL.IND := VAL/VAL[YEAR==2000], by = GRP]
注意:base
年对结果有点混乱。在示例中,'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])
此处,如果我们需要将VAL/VAL[YEAR==2000]
替换为VAL/VAL[which.min(YEAR)]
base R
选项split/unsplit
。我们通过“GRP”列split
数据集将data.frame
转换为list
个数据帧,使用list
循环遍历lapply
输出,创建一个使用transform
(或within
)的新列,并将添加了列的list
转换为data.frame
的单个unsplit
。
unsplit(lapply(split(df, df$GRP), function(x)
transform(x, VAL.IND= VAL/VAL[YEAR==2000])), df$GRP)
请注意,我们也可以使用do.call(rbind
代替unsplit
。但是,我更喜欢unsplit
获得与原始数据集相同的行顺序。
答案 1 :(得分:2)
这是围绕by()
建立的另一种基础R方法:
df$VAL.IND <- do.call(c,by(df,df$GRP,function(g) g$VAL/g$VAL[which.min(g$YEAR)]));
df;
## YEAR GRP VAL VAL.IND
## 1 2000 A 3 1.0000000
## 2 2001 A 1 0.3333333
## 3 2002 A 2 0.6666667
## 4 2000 B 6 1.0000000
## 5 2001 B 5 0.8333333
## 6 2002 B 4 0.6666667