如何用dplyr的across函数实现行内相对频率计算?
正确实现方式
这里有几种简洁的方法用dplyr的across实现行内相对频率计算:
方法一:先计算行总和(效率更高)
先新增一个临时行总和列,再基于它计算各变量的比例,最后可选择删除临时列:
want <- have |> # 计算所有目标列的行总和 mutate(row_total = rowSums(pick(everything())), # 对每个变量计算比例,自动生成带_prop后缀的列名 across(everything(), ~ .x / row_total, .names = "{.col}_prop"), # 可选:删除临时的行总和列 row_total = NULL)
方法二:直接在across内计算行总和
如果数据量不大,也可以省略临时列,直接在across的函数里计算行总和:
want <- have |> mutate(across(everything(), ~ .x / rowSums(pick(everything())), .names = "{.col}_prop"))
或者用cur_data()指代当前数据框,效果完全一致:
want <- have |> mutate(across(everything(), ~ .x / rowSums(cur_data()), .names = "{.col}_prop"))
原代码错误原因
你之前的代码存在两处问题:
- 语法结构错误:
across(everything()), . / rowSums(.)不符合across的调用规则,across的第二个参数必须是一个函数(或公式形式的函数) - 指代对象错误:单独的
.在across函数外虽指代整个数据框,但放在该位置语法无效;如果放在across函数内,.指代的是当前处理的单个列,rowSums(.)会报错——因为单个列是向量,不是rowSums要求的矩阵/数据框类型。
精准匹配目标变量
如果你的数据框里还有其他非目标列,可以用starts_with("x")精准选择前缀为x的变量,避免误处理:
want <- have |> mutate(row_total = rowSums(pick(starts_with("x"))), across(starts_with("x"), ~ .x / row_total, .names = "{.col}_prop"), row_total = NULL)
内容的提问来源于stack exchange,提问作者pyll
相关产品推荐
相关产品推荐

