我用这段代码来计算我的一张表的相对丰度(列的celltotal)。我不明白.和~函数是如何工作的。
构造 ~./sum(x)
严格来说是一种特殊类型的R对象,称为 公式
class(~./sum(x))
#> [1] "formula"
然而,在整齐逆函数中,如 mutate_all
,取此公式并将其转化为 兰姆达函数,它是一个匿名函数(即一个没有命名的函数,是作为调用另一个函数时传递的参数写入的)。
在内部,公式被转换为一个函数,它的名字是 rlang::as_function
. 假设我们想写一个函数,只是将二加到一个变量上。在基础R中,我们可以写
add_two <- function(var){
return(var + 2)
}
add_two(5)
#> [1] 7
在整洁的宇宙中,我们可以用一个公式作为这个函数的简写,其中的 .
成为 "作为函数第一个参数传递的变量 "的简写。
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必须作为数据框架中的一列或调用环境中的一个变量存在。
这样做的原因是它可以节省输入和缩短代码行数。在对另一个函数的调用中插入一个函数,往往会导致代码混乱和格式化不良。这种速记方法有助于防止这种情况的发生。
你可以在tidyverse中阅读更多关于匿名函数以及如何使用它们的信息 此处
假设我们有这个数据集。
dataset <- data.frame(a = c(1,2,3,4),
b = c(2,3,4,5),
c = c(3,4,5,6))
你想把所有的向量除以总数(即向量a=110, 210, 310, 410)。为了避免对所有变量进行书写,你可以使用 mutate_all
,然后用 .funs
其中说做一个函数,将点代表的每个向量中的所有值除以该向量中所有值的和。
dataset %>% mutate_all(.funs = ~./sum(.))
希望这能帮到你。
mutate_all 将 .funs 中的函数应用于所有值。每个值(.)除以sum(x),得到 "相对丰度",它本质上是总价值的分数,也就是sum(x)。你可以把~看作是 "函数"。所以你是说数据框中的每个单元格都是自己的函数除以总和。