【问题标题】:Longer object length is not a multiple of shorter object length while using mutate使用 mutate 时,较长的对象长度不是较短对象长度的倍数
【发布时间】:2020-07-15 22:20:59
【问题描述】:

我正在尝试为 df 的每一行计算函数 EX_A0 的值并将其添加为新列,但我得到“更长的对象长度不是更短的对象长度的倍数”错误。当我过滤掉一行并只为一行做时,没有错误。两行的 EX_A0 的结果都是数字,并且只有一维。我不明白为什么我会收到这个错误。我会很感激你的帮助。这是我的代码:

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) )

【问题讨论】:

  • 你能描述一下你对 EQ_A0 使用了什么函数吗?您已显示 EX_A0。
  • 对不起,我刚刚更正了。
  • 变异有效。这不是错误,只是警告。出现警告是因为length(dgamma(tau, shape=S_a, scale = lambda_a*c, log = TRUE))21length(pgamma(T, shape=S_a, scale = lambda_a*c, lower.tail = TRUE, log.p=TRUE))2。在pgamma 中使用T(RUE) 作为参数的原因是什么?你的意思是tau
  • T 实际上是 30,我忘了补充。

标签: r function error-handling dplyr integral


【解决方案1】:

问题在于EQ_A0 不是参数S_acc 的向量化函数。警告(不是错误)

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_acc 是长度为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 执行的操作)。

要解决此问题,您可以使用 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

reprex package (v0.3.0) 于 2020-04-04 创建

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 2021-11-14
    相关资源
    最近更新 更多