【问题标题】:Why does ifelse convert a data.frame to a list: ifelse(TRUE, data.frame(1), 0)) != data.frame(1)?为什么 ifelse 将 data.frame 转换为列表:ifelse(TRUE, data.frame(1), 0)) != data.frame(1)?
【发布时间】:2011-09-12 17:39:06
【问题描述】:

如果为 TRUE,我想从函数返回 data.frame,否则使用 return(ifelse(condition, mydf, NA)) 返回 NA

但是,ifelse 会从 data.frame 中删除列名。

为什么这些结果不同?

> data.frame(1)
  X1
1  1
> ifelse(TRUE, data.frame(1), NA)
[[1]]
[1] 1

来自 dput() 的一些额外见解:

> dput(ifelse(TRUE, data.frame(1), 0))
list(1)
> dput(data.frame(1))
structure(list(X1 = 1), .Names = "X1", row.names = c(NA, -1L), 
          class = "data.frame")

【问题讨论】:

    标签: class function r if-statement


    【解决方案1】:

    ifelse 通常用于矢量化比较,并具有以下副作用:正如 ?ifelse 中所说,

    ‘ifelse’ returns a value with the same shape as ‘test’ ...
    

    所以在这种情况下(test 是长度为 1 的向量)它会尝试将数据帧转换为长度为 1 的“向量”(在这种情况下为列表)...

    return(if (condition) mydf else NA)
    

    作为一般设计点,无论如何我都会尝试返回相同结构的对象,所以我可能更喜欢

    if (!condition) mydf[] <- NA
    return(mydf)
    

    作为一般规则,我发现 R 用户(尤其是来自其他编程语言的用户)一开始只使用 if,花一些时间发现 ifelse,然后过度使用它一段时间,后来发现你真的想在逻辑上下文中使用if&amp;&amp;&amp; 也会发生类似的情况。

    另见:

    【讨论】:

    • @Ben 感谢您的提示。我没有意识到mydf[] &lt;- NA 是一个选项。
    • @Ben 我会在后续函数中将if(is.na(myfn())) 的使用更改为if(sum(is.na(myfn()) &gt;0) 吗?如果您需要澄清,我可以发布一个单独的问题。
    • 可能只是if(all(is.na(mydf))) ?
    • if(any(is.na(mydf))) 以匹配您之前的逻辑
    • 我认为返回一个空数据框比返回一个充满缺失的数据框更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    • 1970-01-01
    相关资源
    最近更新 更多