我已经知道如何通过数据表中的名称和数字来调用列。
我有兴趣以更灵活的方式调用和执行 转化 。例如...假设我正在使用灵活创建的数据库(J可以是任何东西)。
J = 3
set.seed(1)
temp0 = do.call(CJ, replicate(J, rnorm(10,0,1), simplify = FALSE))
tempp = do.call(CJ, replicate(J, seq(0,1,length.out=10), simplify = FALSE))
setnames(temp0, paste0('beta', 1:J))
setnames(tempp, paste0('p', 1:J))
temp0[,pc:=rnorm(10,-1,.1)]
temp3 = cbind(temp0,tempp)
提供输出
> temp3
beta1 beta2 beta3 pc p1 p2 p3
1: -0.8356286 -2.214700 -1.98935170 -0.8641320 0 0 0.0000000
2: -0.8356286 -2.214700 -1.47075238 -1.0102788 0 0 0.1111111
3: -0.8356286 -2.214700 -0.47815006 -0.9612328 0 0 0.2222222
4: -0.8356286 -2.214700 -0.15579551 -1.0053805 0 0 0.3333333
5: -0.8356286 -2.214700 -0.05612874 -1.1377060 0 0 0.4444444
---
996: 1.5952808 1.511781 0.07456498 -1.0414995 1 1 0.5555556
997: 1.5952808 1.511781 0.41794156 -1.0394290 1 1 0.6666667
998: 1.5952808 1.511781 0.61982575 -1.0059313 1 1 0.7777778
999: 1.5952808 1.511781 0.78213630 -0.8899975 1 1 0.8888889
1000: 1.5952808 1.511781 0.91897737 -0.9236824 1 1 1.0000000
然后我想创建一个称为denom和pi {j}(每个J代表一个变量)的变量,例如,它遵循以下公式。
temp3[,denom:=(1+exp(beta1+pc*p1) + exp(beta2+pc*p2) + exp(beta3+pc*p3))]
temp3[,pi1:=(exp(beta1+pc*p1)/denom)]
temp3[,pi2:=(exp(beta2+pc*p2)/denom)]
temp3[,pi3:=(exp(beta3+pc*p3)/denom)]
提供输出:
> temp3
beta1 beta2 beta3 pc p1 p2 p3 denom pi1 pi2 pi3
1: -0.8356286 -2.214700 -1.98935170 -0.8641320 0 0 0.0000000 1.679572 0.2581621 0.06500839 0.08143983
2: -0.8356286 -2.214700 -1.47075238 -1.0102788 0 0 0.1111111 1.748145 0.2480354 0.06245836 0.11747135
3: -0.8356286 -2.214700 -0.47815006 -0.9612328 0 0 0.2222222 2.043484 0.2121876 0.05343145 0.24502052
4: -0.8356286 -2.214700 -0.15579551 -1.0053805 0 0 0.3333333 2.154850 0.2012214 0.05067002 0.28403911
5: -0.8356286 -2.214700 -0.05612874 -1.1377060 0 0 0.4444444 2.112984 0.2052083 0.05167398 0.26985329
---
996: 1.5952808 1.511781 0.07456498 -1.0414995 1 1 0.5555556 4.944346 0.3518806 0.32369194 0.12217626
997: 1.5952808 1.511781 0.41794156 -1.0394290 1 1 0.6666667 5.106751 0.3413962 0.31404743 0.14873716
998: 1.5952808 1.511781 0.61982575 -1.0059313 1 1 0.7777778 5.311170 0.3394384 0.31224650 0.16003264
999: 1.5952808 1.511781 0.78213630 -0.8899975 1 1 0.8888889 5.877735 0.3444218 0.31683070 0.16861387
1000: 1.5952808 1.511781 0.91897737 -0.9236824 1 1 1.0000000 5.753231 0.3402198 0.31296531 0.17299948
但是,这是硬编码为3的,我该如何对任意J执行此操作?这个问题非常困难,因为它似乎涉及调用列号并同时进行转换。
答案 0 :(得分:1)
远非如此,但是您可以使用Map
来循环遍历使用mget
选择并分配给"pi1/2/3"
的每个不同输入。我已经稍微改变了函数的顺序,以首先计算基本的重复部分,然后是分母,然后除以分母:
J = 3
temp3[,
(paste0("pi",seq(J))) := Map(
function(b,pc,p) exp(b + pc * p),
mget(paste0("beta", seq(J))),
.(pc),
mget(paste0("p", seq(J)))
)
]
temp3[, denom := 1 + Reduce(`+`, mget(paste0("pi", seq(J))) ) ]
temp3[, (paste0("pi",seq(J))) := lapply(mget(paste0("pi", seq(J))), `/`, denom) ]
似乎给出相同的结果:
temp3[, .(pi1,pi2,pi3,denom)]
# pi1 pi2 pi3 denom
# 1: 0.2581621 0.06500839 0.08143983 1.679572
# 2: 0.2480354 0.06245836 0.11747135 1.748145
# 3: 0.2121876 0.05343145 0.24502052 2.043484
# 4: 0.2012214 0.05067002 0.28403911 2.154850
# 5: 0.2052083 0.05167398 0.26985329 2.112984
# ---
# 996: 0.3518806 0.32369194 0.12217626 4.944346
# 997: 0.3413962 0.31404743 0.14873716 5.106751
# 998: 0.3394384 0.31224650 0.16003264 5.311170
# 999: 0.3444218 0.31683070 0.16861387 5.877735
#1000: 0.3402198 0.31296531 0.17299948 5.753231