为啥 mutate() 和 add_column() 不接受相同的基本参数?

Posted

技术标签:

【中文标题】为啥 mutate() 和 add_column() 不接受相同的基本参数?【英文标题】:Why do mutate() and add_column() not accept the same basic arguments?为什么 mutate() 和 add_column() 不接受相同的基本参数? 【发布时间】:2018-07-07 16:24:21 【问题描述】:

我经常希望在特定索引处添加一个新列; mutate() 没有一个简单的实现,而 add_column() 通过 .before 和 .after 参数实现。我希望这两个函数在简单的设置中表现相同,但事实并非如此。下面是将行索引转换为新变量的 MWE。 R 文档没有说清楚:为什么这两个函数的基本语法不同?

dat <- as.tibble(matrix(rnorm(1e4), nrow=100))
dat1 <- dat %>% mutate(id=row_number()) # works as expected
dat2 <- dat %>% add_column(id=row_number()) # throws error
dat3 <- dat %>% add_column(id=1:nrow(dat), .before=1) # works, but harder to read

【问题讨论】:

?row_number 的示例中,它表示row_number can be used with single table verbs without specifying x (for data frames and databases that support windowing)add_row 不是 dplyr 动词,因此需要 row_number 的参数(但要小心;它返回排名)。更简单:rowid_to_column rowid_to_column 的重要提示——绝对有助于发布的用例;尽管我仍然对这两个 tidyverse 函数之间看似脱节的更广泛问题感到好奇。 【参考方案1】:

如果你检查这两个函数的代码,你会得到一些线索。

dplyr::变异

function (.data, ...) 

    UseMethod("mutate")

<environment: namespace:dplyr>

tibble::add_column

function (.data, ..., .before = NULL, .after = NULL) 

    df <- tibble(...)
    if (ncol(df) == 0L) 
        return(.data)
    
    if (nrow(df) != nrow(.data)) 
        if (nrow(df) == 1) 
            df <- df[rep(1L, nrow(.data)), ]
        
        else 
            stopc("`.data` must have ", nrow(.data), pluralise_n(" row(s)", 
                nrow(.data)), ", not ", nrow(df))
        
    
    extra_vars <- intersect(names(df), names(.data))
    if (length(extra_vars) > 0) 
        stopc(pluralise_msg("Column(s) ", extra_vars), pluralise(" already exist[s]", 
            extra_vars))
    
    pos <- pos_from_before_after_names(.before, .after, colnames(.data))
    end_pos <- ncol(.data) + seq_len(ncol(df))
    indexes_before <- rlang::seq2(1L, pos)
    indexes_after <- rlang::seq2(pos + 1L, ncol(.data))
    indexes <- c(indexes_before, end_pos, indexes_after)
    .data[end_pos] <- df
    .data[indexes]

<environment: namespace:tibble>

首先,您会注意到它们来自两个不同的包,尽管它们都是 tidyverse 的一部分。

其次,你会看到mutate 使用了一个指定的方法,而add_column 更像是一个用r 编写的便利函数,带有一些rlang 魔法。

我不确定这两个包的路线图,但是,如果还没有提出或分叉项目并提供拉取请求,我相信您可以提出增强功能。这将是一个有用的补充。

更新

这已在tidyverse/dplyr 中提出,似乎正在开发中,但尚未计划。

【讨论】:

关于 tibble 函数和 dplyr 函数的路线图是否有任何进一步的更新或任何其他讨论?

以上是关于为啥 mutate() 和 add_column() 不接受相同的基本参数?的主要内容,如果未能解决你的问题,请参考以下文章

引用的 add_column (Rails)

为啥activerecord乐观锁定每行只工作一次?

当 add_column 使用默认选项并且没有 null:false 时是不是有可能插入 null

rails add_column 具有默认值但默认值不生效

logstash的mutate插件

logstash的mutate插件