【问题标题】:Why subset doesn't mind missing subset argument for dataframes?为什么子集不介意缺少数据帧的子集参数?
【发布时间】:2016-09-06 12:00:48
【问题描述】:

通常我想知道神秘错误来自哪里,但现在我的问题是神秘缺乏错误来自哪里。

numbers <- c(1, 2, 3)
frame <- as.data.frame(numbers)

如果我输入

subset(numbers, )

(所以我想取一些子集但忘记指定子集函数的子集参数)然后 R 提醒我(应该如此):

subset.default(numbers, ) 中的错误:
缺少参数“子集”,没有默认值

但是当我输入时

subset(frame,)

(所以与data.frame 而不是向量相同),它不会给出错误,而是只返回(完整)数据帧。

这里发生了什么?为什么我没有收到当之无愧的错误消息?

【问题讨论】:

    标签: r dataframe subset


    【解决方案1】:

    tl;drsubset 函数调用不同的函数(具有不同的方法),具体取决于它所提供的对象类型。在上面的例子中,subset(numbers, ) 使用subset.defaultsubset(frame, ) 使用subset.data.frame


    R 内置了几个面向对象的系统。最简单和最常见的称为 S3。这种 OO 编程风格实现了 Wickham 所说的“通用函数 OO”。在这种 OO 风格下,称为泛型函数的对象查看对象的类,然后将适当的方法应用于对象。如果不存在直接方法,则始终有可用的默认方法。

    要更好地了解 S3 和其他 OO 系统的工作原理,您可以查看Advanced R 站点的相关部分。为对象找到正确方法的过程称为方法分派。您可以在帮助文件?UseMethod 中阅读更多相关信息。

    ?subset 的详细信息部分所述,subset 函数“是一个通用函数”。这意味着subset 在第一个参数中检查对象的类,然后使用方法分派将适当的方法应用于对象。

    泛型函数的方法编码为

    .

    可以使用methods(&lt;generic function name&gt;) 找到。对于subset,我们得到

    methods(subset)
    [1] subset.data.frame subset.default    subset.matrix    
    see '?methods' for accessing help and source code
    

    表示如果对象有data.frame类,那么subset调用subset.data.frame的方法(函数)。定义如下:

    subset.data.frame
    function (x, subset, select, drop = FALSE, ...) 
    {
        r <- if (missing(subset)) 
            rep_len(TRUE, nrow(x))
        else {
            e <- substitute(subset)
            r <- eval(e, x, parent.frame())
            if (!is.logical(r)) 
                stop("'subset' must be logical")
            r & !is.na(r)
        }
        vars <- if (missing(select)) 
            TRUE
        else {
            nl <- as.list(seq_along(x))
            names(nl) <- names(x)
            eval(substitute(select), nl, parent.frame())
        }
        x[r, vars, drop = drop]
    }
    

    请注意,如果缺少子集参数,则第一行

        r <- if (missing(subset)) 
            rep_len(TRUE, nrow(x))
    

    产生一个与 data.frame 和最后一行长度相同的 TRUES 向量

        x[r, vars, drop = drop]
    

    将此向量输入到行参数中,这意味着如果您不包含子集参数,则subset 函数将返回 data.frame 的所有行。

    methods 调用的输出中可以看出,subset 没有原子向量的方法。这意味着,作为你的错误

    subset.default(numbers, ) 中的错误

    当您将subset 应用于向量时,R 调用定义为的subset.default 方法

    subset.default
    function (x, subset, ...) 
    {
        if (!is.logical(subset)) 
            stop("'subset' must be logical")
        x[subset & !is.na(subset)]
    }
    

    当缺少子集参数时,subset.default 函数会抛出 stop 错误。

    【讨论】:

      猜你喜欢
      • 2021-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      相关资源
      最近更新 更多