Большая длина объекта не кратна короткой длине объекта при использовании mutate - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь вычислить значение функции EX_A0 для каждой строки df и добавить его в качестве нового столбца, но я получаю сообщение об ошибке «длина объекта не кратна длине объекта». Когда я отфильтровываю строку и делаю это только для одной строки, ошибки не возникает. Результат EX_A0 для обеих строк имеет числовое значение c и имеет только одно измерение. Я не понимаю, почему я получаю эту ошибку. Буду признателен за вашу помощь. Вот мой код:

EQ_A0 <- function(S_a, lambda_a, c){
  integrate(integrand2, 0, 30, S_a, lambda_a, c, subdivisions=2000, rel.tol=.Machine$double.eps^.05)$value
}

integrand2 <- function(tau, S_a, lambda_a, c){
  exp(log(tau)+h_A0(tau, S_a, lambda_a, c))
}
h_A0 <- function(tau, S_a, lambda_a, c){
  dgamma(tau, shape=S_a, scale = lambda_a*c, log = TRUE) - pgamma(30, shape=S_a, scale = lambda_a*c, lower.tail = TRUE, log.p=TRUE)
}

df <- data.frame(cc=c(0.06329820, 0.05141647), ya=c(31, 256), Sa=c(31,256), yb=c(2865, 742), Sb=c(2993, 1348))

df %>% 
  mutate(asd=EQ_A0(Sa, 350, cc))


Следующее сработало, но я до сих пор не понимаю, почему не работает mutate.

mapply(EQ_A0, df$Sa, lambda_a, df$cc)
cbind(df,f = mapply(EQ_A0, df$Sa, 350, df$cc) )

1 Ответ

0 голосов
/ 04 апреля 2020

Проблема в том, что EQ_A0 не является векторизованной функцией для параметров S_a и cc. Предупреждение (не ошибка)

Warning message:
In dgamma(tau, shape = S_a, scale = lambda_a * c, log = TRUE) -  :
  longer object length is not a multiple of shorter object length

возникает внутри h_A0 и связано с тем, что S_a и cc являются 2-векторами длины вместо скаляров (Вы можете проверить это, добавив оператор browser()).

Как я уже упоминал в своем комментарии, результат dgamma(tau, shape=S_a, scale = lambda_a*c, log = TRUE) - это вектор длины 21, а результат pgamma(30, shape=S_a, scale = lambda_a*c, lower.tail = TRUE, log.p=TRUE) - это вектор длины 2 , Следовательно, при вычитании последнего из первого R возникает предупреждение, поскольку 21 (длина более длинного объекта) не кратно 2 (длина более короткого объекта). R все еще выполняет вычисления, но выдает ложный результат.

Кроме того, это не относится к mutate, который можно проверить с помощью EQ_A0(df$Sa, 350, df$cc) (это то, что вы пытаетесь сделать с mutate).

Для решения этой проблемы у вас есть l oop над строками параметров в вашем фрейме данных с map2_dbl (эквивалент mapply(EQ_A0, df$Sa, lambda_a, df$cc)) или с использованием rowwise:

library(dplyr)
library(purrr)

EQ_A0 <- function(S_a, lambda_a, c){
  integrate(integrand2, 0, 30, S_a, lambda_a, c, subdivisions=2000, rel.tol=.Machine$double.eps^.05)$value
}

integrand2 <- function(tau, S_a, lambda_a, c){
  exp(log(tau)+h_A0(tau, S_a, lambda_a, c))
}

h_A0 <- function(tau, S_a, lambda_a, c){
  #browser()
  dgamma(tau, shape=S_a, scale = lambda_a*c, log = TRUE) - pgamma(30, shape=S_a, scale = lambda_a*c, lower.tail = TRUE, log.p=TRUE)
}

df <- data.frame(cc=c(0.06329820, 0.05141647), ya=c(31, 256), Sa=c(31,256), yb=c(2865, 742), Sb=c(2993, 1348))

# Solution 1: use map2_dbl to loop over parameters
df %>% 
  mutate(asd = map2_dbl(Sa, cc, ~ EQ_A0(.x, 350, .y)))
#>           cc  ya  Sa   yb   Sb      asd
#> 1 0.06329820  31  31 2865 2993 29.02379
#> 2 0.05141647 256 256  742 1348 29.88251

# Solution 1: use rowwise to loop over parameters
df %>% 
  rowwise() %>% 
  mutate(asd=EQ_A0(Sa, 350, cc)) %>% 
  ungroup()
#> # A tibble: 2 x 6
#>       cc    ya    Sa    yb    Sb   asd
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 0.0633    31    31  2865  2993  29.0
#> 2 0.0514   256   256   742  1348  29.9

Создано в 2020-04-04 пакетом представ (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...