在 `dplyr::mutate()` 中引用特定值

Refer particular value in `dplyr::mutate()`

我有以下代码:

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% 会产生不正确的结果。

我认为在尝试变异之前将 cf 中的 CPIAUCSL 列加入 tmp 可能更容易:

cf$year = as.numeric(cf$year)
tmp = tmp %>% inner_join(cf, by = "year") %>% mutate(infl.price = price / CPIAUCSL)

您的 cf 结构是一个不友好的列表列表。如果有

会更好
cf$year <- sapply(cf$year, function(x) as.numeric(head(unlist(strsplit(x, "-")), 1)))

其中至少 returns 一个简单的向量。

此外,子集运算符 [] 未针对此类运算正确矢量化。 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