Мне нужно реплицировать некоторые столбцы и эффективно добавить rnorm в другой. - PullRequest
1 голос
/ 26 марта 2019

У меня есть data.frame с именем datos со столбцами

names <- c("TIPO","CODIGO","CANTIDAD","AVG_INGRESO_TOTAL","STDEV_INGRESO_TOTAL")

Где Tipo и Codigo вместе являются первичными ключами.

Тогда "Cantidad" - это количество сэмплов, которое мне нужно для этого ПК, с AVG_INGRESO_TOTAL в качестве среднего значения и STDEV_INGRESO_TOTAL в качестве отклонения.

Мне нужен в результате data.frame со столбцами

c("TIPO","CODIGO","INGRESO")

где INGRESOS - это значение отсчетов, повторяемых "CANTIDAD" раз для каждого "TIPO", "CODIGO".

Я уже решил проблему следующим образом:

for (i in 1:nrow(datos)) {
  d<-rnorm(datos$CANTIDAD[i],datos$AVG_INGRESO_TOTAL[i],datos$STDEV_INGRESO_TOTAL[i])

  for (h in 1:datos$CANTIDAD[i]) {
   vec <-data.frame(datos$TIPO[i],datos$CODIGO[i],d[h])
   names(vec)<-c("TIPO","CODIGO","INGRESO")
   distribucion <- rbind(distribucion,vec)
  }
}

Но в результате получается неэффективный сценарий, который занимает более одного часа для суммирования ("CANTIDAD") = 1.000.0000.

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Рассмотрим by для поднабора ваших первичных ключей и построения фреймов данных с каждой итерацией подмножества. Ниже строится список фреймов данных до rbind один раз вне цикла.

df_list <- by(datos, datos[c("TIPO", "CODIGO")], function(sub) {
   d <- rnorm(sub$CANTIDAD, sub$AVG_INGRESO_TOTAL[1], sub$STDEV_INGRESO_TOTAL[1])

   data.frame(TIPO=sub$TIPO[1], CODIGO=sub$CODIGO[1], INGRESO=d)
})

distribucion <- do.call(rbind, df_list)
0 голосов
/ 27 марта 2019

Похоже, что для каждой пары TIPO и CODIGO вы хотите, чтобы случайно сгенерированное число создавалось при CANTIDAD отрисовках нормальной случайной величины со средним значением AVG_INGRESO_TOTAL и стандартным отклонением STDEV_INGRESO_TOTAL.

Если это так, первое, что нужно понять, это то, что вам не нужно имитировать CANTIDAD розыгрыши:

  • Если X_1, X_2, ..., X_n - все нормальные случайные величины со средним M и стандартным отклонением S
  • Тогда сумма (X_1, X_2, ..., X_n) является нормальной со средним n*M и стандартным отклонением sqrt(n)*S

Следовательно, ваш запрос может быть уменьшен до:

answer <- datos %>%
    mutate(INGRESO = rnorm(1, CANTIDAD*AVG_INGRESO_TOTAL, sqrt(CANTIDAD)*STDEV_INGRESO_TOTAL) %>%
    select(TIPO, CODIGO, INGRESO)
...