【问题标题】:`print` function in `ifelse``ifelse` 中的 `print` 函数
【发布时间】:2015-10-16 07:31:22
【问题描述】:

我想知道为什么ifelse(1<2,print("true"),print("false")) 会返回

[1] "true"
[1] "true"

ifelse(1<2,"true","false") 返回

[1] "true"

我不明白为什么ifelse 中的print 会两次返回"true"

【问题讨论】:

  • 可能与this有关。
  • 另请注意,ifelse 确实设计用于应用于向量,而不是标量,所以也许你最好还是使用if (1<2) print("true") else print("false")
  • 请注意,如果您分配它,例如z <- ifelse(1 < 2, print("true"), print("false")),新对象将保持正确的结果。
  • 一个古老的故事说,每当一个非程序员的家伙说出bug这个词,程序员就会死去。你必须拍手让他重新活过来。
  • ifelse(1 < 2, print(print("true")), print("false")) 是另一种了解正在发生的事情的方法。然后反转运算符。

标签: r if-statement


【解决方案1】:

这是因为ifelse 总是会返回一个值。当您运行ifelse(1<2,print("true"),print("false")) 时,您的yes 条件被选中。这个条件是在控制台上打印"true"的函数调用,它确实如此。

但是print() 函数也返回它的参数,但是是不可见的(例如赋值),否则在某些情况下你会打印两次该值。当yes 表达式被求值时,它的结果就是ifelse 返回的结果,而ifelse 不会无形地返回,所以它会打印结果,因为它是在全局环境中运行的并且没有任何赋值。

我们可以测试一些变化并检查发生了什么。

> result <- print("true")
[1] "true" # Prints because the print() function was called.
> result
[1] "true" # The print function return its argument, which was assigned to the variable.

> ifelse(1<2, {print("true");"TRUE"},print("false"))
[1] "true" #This was printed because print() was called
[1] "TRUE" #This was printed because it was the value returned from the yes argument

如果我们分配这个ifelse()

> result <- ifelse(1<2, {print("true");"TRUE"},print("false"))
[1] "true"
> result
[1] "TRUE"

我们还可以看看同时评估两个条件条件的情况:

> ifelse(c(1,3)<2, {print("true");"TRUE"},{print("false");"FALSE"})
[1] "true" # The yes argument prints this
[1] "false" # The no argument prints this
[1] "TRUE"  "FALSE" # This is the returned output from ifelse()

您应该使用ifelse 创建新对象,而不是根据条件执行操作。为此,请使用 if elseThe R Inferno 有很好的部分 (3.2) 关于两者之间的区别。

【讨论】:

    【解决方案2】:

    只是为 Molx 的出色回答添加一些论据。 发生这种情况的原因之一在于:

    length(print("true"))
    [1] "true"
    [1] 1
    length(length(print("true")))
    [1] "true"
    [1] 1
    length(length(length(print("true"))))
    [1] "true"
    [1] 1
    

    ...等等...

    在R手册中是这样说的:

    是测试的真实元素的返回值

    注意 values,而不是 value,这里我们有两个值:一个是 print 函数的对象(很可能必须打印“true”它是对函数的调用,在本例中为 print,因此具有带有 true 的字符向量),另一个是输出 print "true",它是 ifelse 语句的正确元素。

    可以通过以下方式避免:

     ifelse(1 < 2, "true" , "false" )
    [1] "true"
    

    【讨论】:

    • 非常感谢您的反对票。与往常一样,投反对票后永远不会发表评论。
    • 这部分不正确:这里我们有两个值:一个是打印函数的对象(必须打印“true”),另一个是打印“true”。 你有两个不同的向量,每个元素一个,第二个是来自ifelse()only 结果。第一个只是print()的结果,根本不是ifelse()结果的一部分。
    • @RichardScriven 我已经编辑了这个问题,现在我认为它更清楚了。我们的想法是一样的,也许我没有写清楚。我知道现在很清楚了。
    【解决方案3】:

    不是同时打印 TRUE 和返回 TRUE 吗?

    所以例如使用 cat 而不是 print 会改变输出...

    这基本上和ulfelders的评论有关。

    【讨论】:

    • mmm use cat 会抛出错误信息和警告,因为它解释了它的参数;试试ifelse(1&lt;2, cat("true"), cat("false"))
    最近更新 更多