我正试图使用mutate
和case_when
在数据帧中创建一个新列,但我得到了意外的结果。
以下是我的数据子集的dput:Pastebin。
其目的是计算在多个完全独立的市场中产品的自有和交叉价格弹性。我的想法是使用case_when为自己和交叉弹性使用不同的表达式,并使用唯一的乘积标识符(IDprod_un_j
和IDprod_un_l
(从另一个矩阵中对一些值进行子集设置。这是我正在使用的代码:
elast_small %<>%
mutate(
eta_jlm_rc = case_when(
IDprod_j == IDprod_l ~ (-price_j/share_j) * rowMeans(-alpha_i_rc * share_i_small[IDprod_un_j,] * (1-share_i_small[IDprod_un_j,])),
IDprod_j != IDprod_l ~ (-price_l/share_j) * rowMeans(alpha_i_rc * share_i_small[IDprod_un_j,] * share_i_small[IDprod_un_l,])
)
)
这运行时没有错误,但当我尝试验证结果时,我得到了不同的值:
> -elast_small$price_j[1] / elast_small$share_j[1] * mean(-alpha_i_rc * share_i_small[1,] * (1-share_i_small[1,]))
[1] -10.02669
> elast_small$eta_jlm_rc[1]
[1] -14.83231
我在这里错过了什么?
如果您按产品类型j
和l
分组,然后在交给mutate()
语句之前使(-price/share)
乘以的变量为
tmp <- elast_small %>%
group_by(IDprod_un_j,IDprod_un_l) %>%
mutate(
newvar1 = mean(-alpha_i_rc * share_i_small[IDprod_un_j, ] * (1-share_i_small[IDprod_un_j, ])),
newvar2 = mean(alpha_i_rc * share_i_small[IDprod_un_j, ] * share_i_small[IDprod_un_l, ]),
eta_jlm_rc = case_when(
IDprod_j == IDprod_l ~ (-price_j/share_j) * newvar1,
IDprod_j != IDprod_l ~ (-price_l/share_j) * newvar2
)
)
tmp %>%
select(IDprod_un_j, IDprod_un_l, eta_jlm_rc2) %>%
as.data.frame %>%
head
# IDprod_un_j IDprod_un_l eta_jlm_rc2
# 1 1 1 -10.026692702
# 2 1 2 0.001446025
# 3 1 3 0.005316131
# 4 1 4 0.133027210
# 5 1 5 0.017306581
# 6 1 6 0.063833755
这里缺少的是case_when
没有逐行应用RHS,而是对每种情况一次性应用,因此share_i_small[IDprod_un_j,]
返回一个包含多行的矩阵。向量和矩阵的乘积是在R中按列进行的,因此乘积是不正确的。
这解决了问题:
elast %<>%
mutate(
eta_jlm_rc = case_when(
IDprod_j == IDprod_l ~ (-price_j/share_j) * rowMeans(t(t(share_i[IDprod_ud_j,] * (1-share_i[IDprod_ud_j,])) * -alpha_i_rc)),
IDprod_j != IDprod_l ~ (-price_l/share_j) * rowMeans(t(t(share_i[IDprod_ud_j,] * share_i[IDprod_ud_l,]) * alpha_i_rc))
)
)