mutate_all(.funs=~./sum(x)) 如何工作?

How does mutate_all(.funs=~./sum(x)) work?

我使用此代码计算了我拥有的 table 的相对丰度(cell/total 列)。我不明白 .和 ~ 功能起作用。

mutate_all 将 .funs 中的函数应用于所有值。每个值 (.) 除以 sum(x),得到 "relative abundance",它本质上是总值的分数,即 sum(x)。您可以将 ~ 视为 "function of"。因此,您是说数据框中的每个单元格都是自身除以总和的函数。

假设我们有这个数据集:

dataset <- data.frame(a = c(1,2,3,4),
                      b = c(2,3,4,5),
                      c = c(3,4,5,6))

并且您想将所有向量除以总数(即向量 a = 1/10、2/10、3/10、4/10)。为避免写入所有变量,您可以使用 mutate_all,然后是使用 .funs 的 lambda,它表示创建一个函数,将点表示的每个向量中的所有值除以该点中所有值的总和矢量。

dataset %>% mutate_all(.funs = ~./sum(.))

希望对您有所帮助。

构造 ~./sum(x) 在技术上是一种特殊类型的 R 对象,称为 公式

class(~./sum(x))
#> [1] "formula"

但是,在 mutate_all 等 tidyverse 函数中,这个公式被采用并转换为 lambda 函数,这是一个匿名函数(即一个函数是' 命名并作为在调用另一个函数时传递的参数写入到位)。

在内部,公式被转换为函数rlang::as_function。假设我们想写一个函数,只将两个加到一个变量上。在 base R 中我们可以写

add_two <- function(var){
  return(var + 2)
}

add_two(5)
#> [1] 7

在 tidyverse 中,我们可以使用公式作为此函数的 shorthand,其中 . 变为 shorthand 对于 "the variable that was passed as a first argument to the function":

add_two <- rlang::as_function(~ . + 2)

add_two(5)
#> [1] 7

mutate_all等函数中,公式会自动通过rlang::as_function传递,所以如果我们想在数据框中的每一列中添加两个,而不是写成:

mutate_all(.funs= function(var) {return(var + 2);})

我们可以写

mutate_all(.funs=~.+2)

在您的例子中,公式 ~./sum(x) 有效地转换为

function(var) {
  return(var / sum(x))
}

其中 x 必须作为数据框中的列或调用环境中的变量存在。

采用这种方式的原因是它可以节省输入并缩短代码行。在对另一个函数的调用中插入一个函数通常会导致代码混乱且格式不正确。这种 shorthand 方法有助于防止这种情况。

您可以阅读更多关于匿名函数以及它们如何在 tidyverse 中使用的信息 here