我有以下代码:
library(dplyr)
library(quantmod)
# inflation data
getSymbols("CPIAUCSL", src='FRED')
avg.cpi <- apply.yearly(CPIAUCSL, mean)
cf <- avg.cpi/as.numeric(avg.cpi['1991']) # using 1991 as the base year
cf <- as.data.frame(cf)
cf$year <- rownames(cf)
cf <- tail(cf, 25)
rownames(cf) <- NULL
cf$year <- lapply(cf$year, function(x) as.numeric(head(unlist(strsplit(x, "-")), 1)))
rm(CPIAUCSL)
# end of inflation data get
tmp <- data.frame(year=c(rep(1991,2), rep(1992,2)), price=c(12.03, 12.98, 14.05, 14.58))
tmp %>% mutate(infl.price = price / cf[cf$year == year, ]$CPIAUCSL)
我想得到以下结果:
year price
1991 12.03
1991 12.98
1992 13.64
1992 14.16
但是我收到了一个错误:
Warning message:
In cf$year == tmp$year :
longer object length is not a multiple of shorter object length
使用%in%
会产生错误的结果。
答案 0 :(得分:4)
我认为在您尝试变异之前,将CPIAUCSL
中的cf
列加入tmp
可能会更容易:
cf$year = as.numeric(cf$year)
tmp = tmp %>% inner_join(cf, by = "year") %>% mutate(infl.price = price / CPIAUCSL)
答案 1 :(得分:3)
您的cf
结构是一个不友好的列表列表。
cf$year <- sapply(cf$year, function(x) as.numeric(head(unlist(strsplit(x, "-")), 1)))
至少返回一个简单的向量。
此外,对于此类操作,子集化运算符[]
未正确向量化。 mutate()
函数不会遍历行,它一次对整个列进行操作。当你这样做
cf[cf$year == year, ]$CPIAUCSL
不只有一个year
值,mutate
正在尝试同时执行所有操作。
最好合适地合并数据,然后进行变异。这基本上与你试图在你的版本中进行的伪合并做同样的事情。
你可以做到
tmp %>% left_join(cf) %>%
mutate(infl.price = price / CPIAUCSL) %>%
select(-CPIAUCSL)
获取
year price infl.price
1 1991 12.03 12.03000
2 1991 12.98 12.98000
3 1992 14.05 13.63527
4 1992 14.58 14.14962