Динамический вызов столбца и преобразование в таблице данных часть по номеру часть по имени - PullRequest
0 голосов
/ 19 декабря 2018

Я уже знаю, как вызывать столбцы по имени и номеру в таблице данных.

Мне интересно звонить и делать преобразования , хотя более гибким способом,Например ... предположим, что я работаю с гибко (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?Эта проблема довольно сложна, потому что, кажется, она будет включать вызов номеров столбцов и одновременное выполнение преобразований.

1 Ответ

0 голосов
/ 19 декабря 2018

Это далеко не красиво, но вы можете использовать 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
...