【问题标题】:Error using the "prob" package in an R function在 R 函数中使用“prob”包时出错
【发布时间】:2013-09-29 19:15:20
【问题描述】:

我正在尝试编写一个使用prob 包来计算条件概率的函数。使用该函数时,我继续遇到相同的错误,即找不到函数内的对象。

下面是一个可重现的示例,其中我在没有函数的情况下计算条件概率,然后尝试使用该函数产生相同的结果。我不确定错误是由于 prob 包的限制还是我的错误。

# Load prob package
library(prob)

# Set seed for reproducibility
set.seed(30)

# Sample data frame
sampledata <- data.frame(
  X <- sample(1:10),
  Y <- sample(c(-1, 0, 1), 10, replace=TRUE))

# Set probability space
S <- probspace(sampledata)

# Subset Y between -1 and 0
A <- subset(S, Y>=-1 & Y<=0)

# Subset X greater than 6
B <- subset(S, X>6)

# Compute conditional probability
P <- prob(A, given=B)

以上代码产生以下概率:

> P
[1] 0.25

尝试编写一个函数来计算相同的概率:

# Create function with data frame, variables, and conditional inputs
prob.function <- function(df, variable1, variable2, state1, state2, cond1){
  s <- probspace(df)
  a <- subset(s, variable1>=state1 & variable1<=state2)
  b <- subset(s, variable2>cond1)
  p <- prob(a, given=b)
  return(p)
}

# Demonstrate the function
test <- prob.function(sampledata, Y, X, -1, 0, 6)

此函数给出以下错误:

Error in eval(expr, envir, enclos) : object 'b' not found

您能提供的任何帮助都会很棒。

谢谢!

【问题讨论】:

  • 感谢您的提问,感谢您提供离线错误报告。在玩过它并现在阅读此讨论之后,还有更多工作要做。我期待明天晚些时候 R-Forge 的更新。

标签: r probability


【解决方案1】:

这看起来像是prob 中的一个错误。

当我在 Vanilla R 中运行它时,我得到了同样的错误。但是当我在我的工作区创建一个对象b 时,错误消失了:

> print(b)
Error in print(b) : object 'b' not found
> test <- prob.function(sampledata, Y, X, -1, 0, 6)
Error in eval(expr, envir, enclos) : object 'b' not found
>
> b <- "dummy variable"
> print(b)
[1] "dummy variable"
> test <- prob.function(sampledata, Y, X, -1, 0, 6)
> test
[1] 0.25
>

作为一种临时解决方法,只需在当前环境中创建一个虚拟 b


至于错误,如果您查看prob.default 的源代码(在上面的示例中,prob(a, given=b) 最终会调用它),您将看到以下部分:

if (missing(given)) {
    < cropped >
}
else {
    f <- substitute(given)
    g <- eval(f, x)                  <~~~~ 
    if (!is.logical(g)) {            <~~~~
        if (!is.data.frame(given))   <~~~~
            stop("'given' must be data.frame or evaluate to logical")
        B <- given

    }
    ...
    < cropped >
}

它从g 跳到given,也许是无意的?我会联系包维护者,因为这可能是一个疏忽。

【讨论】:

  • 感谢您的快速回答!我会将此错误通知包作者。
  • 感谢 Ricardo 找出问题所在。
  • @G.JayKerns 完全没有问题。我认为其他prob 方法中可能存在类似问题,可能值得研究。感谢您的包裹
【解决方案2】:

认为这是包 prob 中的错误。

首先,您应该将sampledata 创建为

sampledata <- data.frame(
  X = sample(1:10),
  Y = sample(c(-1, 0, 1), 10, replace=TRUE))

您的原始代码不仅会创建此数据帧,还会在全局环境中创建变量 XY,这些变量会在您稍后调用函数时实际使用。

其次,你不应该在函数内部调用subset()。改用括号子集:

prob.function <- function(df, variable1, variable2, state1, state2, cond1){
  s <- probspace(df)
  a <- s[s[[variable1]]>=state1 & s[[variable1]]<=state2, ]
  b <- s[s[[variable2]]>cond1, ]
  p <- prob(a, given=b)
  return(p)
}

并将variable1variable2 作为字符串传递:

test <- prob.function(sampledata, "Y", "X", -1, 0, 6)

现在你有test==0.25,没有错误。

参考资料:

【讨论】:

  • 嘿@Ferdinand,虽然我认为您关于不使用子集的建议是正确的,但我仍然认为prob 存在一些可疑之处,并且可能是一个错误。请注意根据我的工作环境中函数的不同响应部分,其中与函数的唯一关系是共享对象名称(但该值与函数无关)。更不用说在R --vanilla 中运行时这仍然不起作用:/
  • @RicardoSaporta 你是对的,这是一个错误。他在eval(f, x) 中忘记了enclos=parent.frame()。此时,f 包含符号 bx 包含数据帧 a。由于eval 的默认封闭是调用它的框架,因此解析器将在prob 的命名空间及以上查找b,绕过真正的b 所在的“调用堆栈”。当您创建一个虚拟b 时,eval 不会抛出错误,is.logical(g) 是 FALSE(它是一个字符串)但 is.data.frame(given) 是 TRUE,因为 given 是真正的 b,而不是承诺。好难找的bug! :-)
  • 嗨@Ferdinand.kraft,感谢您提供非常有用的建议,尤其是关于何时/如何使用子集()。现在看来问题出在包中的一个错误上,我已经向包作者发送了一封电子邮件,其中包含指向此讨论的链接。再次感谢!
  • 谢谢你,费迪南德。当我第一次开始研究这个时,我走的是你做的同样的路(使用=而不是&lt;-,等等)。不过,现在我已经阅读了您上面的扩展评论,很明显存在更严重的问题。我会试试你建议的enclose=parent.frame()。再次感谢。
猜你喜欢
  • 2018-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-10
  • 1970-01-01
相关资源
最近更新 更多