楼主: 果子统计
57 0

R语言 rowwise() :按行计算解决方案 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

40%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
20 点
帖子
1
精华
0
在线时间
0 小时
注册时间
2018-3-7
最后登录
2018-3-7

楼主
果子统计 发表于 2025-11-28 16:18:59 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

关键词:dplyr、按行计算、分组行操作、across()函数互补、

rowwise()
c_across()

1. 为什么需要
rowwise()

在实际的数据分析任务中,常常会遇到需要对同一行多个列的值进行聚合操作的情况,例如:

  • 计算每行的平均值、最大值或方差
  • 从多列中提取每行的 top-k 值
  • 将多个字符串列拼接成一个结果字段
  • 将多个评分列相加生成综合得分(composite score)

传统处理方式可能如下所示:

apply(df[, c("a","b","c")], 1, mean)

但这种方式存在明显缺陷:

  • apply
    会将数据强制转换为矩阵,导致原始数据类型信息丢失
  • 与 tidyverse 风格不兼容
  • 难以嵌入到管道链式操作中,如
    mutate()
    summarise()
    等语法结构

为此,dplyr 提供了

rowwise()
—— 它是行级计算模式的开启器,专门用于解决上述问题。

2. 示例数据

以下是一个典型的学生各科成绩数据集,用于后续演示:

library(dplyr)

df <- tibble(
  id = 1:5,
  Math = c(80, 75, 90, 60, 88),
  English = c(85, 78, 92, 65, 90),
  Physics = c(78, 70, 88, 55, 95)
)
df

3. 为何不能直接使用
mutate(mean = mean(Math, English, Physics))

许多用户尝试通过如下代码计算三门课程的平均分:

df %>%
  mutate(mean_score = mean(c(Math, English, Physics)))

然而,这种写法并不会实现逐行计算。其实际行为是:

  • 将 Math、English、Physics 三列合并为一个长度为 15 的长向量(假设有 5 行)—— 见
    mean(c(Math, English, Physics))
  • 计算整个向量的均值(得到单个数值,如 79.6)—— 见
    mean()
  • 将该单一结果重复填充至每一行

最终输出形如:

idMathEnglishPhysicsmean_score
180857879.6
275787079.6
............79.6

这本质上是“全列整体计算 + 广播复制”,而非真正的按行聚合

4.
rowwise()
的核心功能

最基础的应用场景是:对每一行计算多列的平均值。

df %>%
  rowwise() %>%
  mutate(mean_score = mean(c(Math, English, Physics)))

输出示例:

idMathEnglishPhysicsmean_score
180857881.0
275787074.3
...............

关键点在于:

rowwise()
明确告诉 dplyr ——接下来的操作应以行为单位进行,而不是默认的列方向操作。

5. 更优雅的写法:结合
c_across()

为了避免手动列出所有列名,可以使用

c_across()

df %>%
  rowwise() %>%
  mutate(mean_score = mean(c_across(Math:Physics)))

其中,

c_across()
是在 rowwise 模式下的列选择工具,作用是:

  • 将指定的多列组合成一个行内向量
  • 便于传递给需要向量输入的函数进行处理

6. 在每行上执行多个函数

利用

rowwise()
和 mutate 结合,可同时计算每行的多种统计量:

df %>%
  rowwise() %>%
  mutate(
    max_score = max(c_across(Math:Physics)),
    min_score = min(c_across(Math:Physics))
  )

7. 按行拼接非数值型字符串

对于字符型列,也可使用类似方法进行行内拼接:

df %>%
  rowwise() %>%
  mutate(info = paste(Math, English, Physics, sep = "-"))

输出示例:

80-85-78

8.
rowwise()
summarise()
的组合使用

注意与

across
的区别:

  • rowwise()
    支持在 summarise 中逐行聚合,且结果仍保留原始行数
  • 只有在显式调用 ungroup 或移除 rowwise 状态后,才会解除行绑定

例如:

df %>%
  rowwise() %>%
  summarise(mean_score = mean(c_across(Math:Physics)))
输出仍为 5 行,而传统的
group_by
会将结果压缩为 1 行汇总值。

9.
rowwise()
vs
across()
功能对比

维度
rowwise()
across()
操作对象
常见任务求每行的统计值对多列执行相同变换
与 summarise 的关系保留原始行数压缩为汇总行
典型语句
mean(c_across())
across(cols, fun)
示例用途每行平均、拼接字符串对多列统一求 mean、sd、归一化等

简单判断标准:

  • 若需对多列做相同操作 → 使用 across()
  • 若需对单行跨列聚合 → 使用 rowwise()

10. 如何正确移除
rowwise()

在使用

rowwise()
后,数据框仍携带 rowwise 属性 ——
rowwise

如果后续希望恢复正常的列操作(如

group_by()
summarise()
),必须先解除该状态。

方法一:使用

ungroup()

df %>%
  rowwise() %>%
  summarise(mean_score = mean(c_across(Math:Physics))) %>%
  ungroup()

方法二:使用

as_tibble()
重置 tibble 状态

df %>%
  rowwise() %>%
  summarise(mean_score = mean(c_across(Math:Physics))) %>%
  as_tibble()

11. 高频应用场景汇总

应用场景代码示例
每行求和
mutate(total = sum(c_across(Math:Physics)))
判断某行是否存在异常值
filter(any(c_across(Math:Physics) > 90))
计算每行 top-2 成绩的平均值
mutate(top2 = mean(sort(c_across(Math:Physics), decreasing = TRUE)[1:2]))
将标签列按行拼接
mutate(label = paste(c_across(Math:Physics), collapse = "_"))

12. 系列总结

group_by()   # 分组
summarise()  # 聚合
across()     # 多列批量操作
rowwise()    # 按行聚合处理
c_across()   # rowwise专属数据抓取器

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:解决方案 WISE R语言 MathEnglish Decreasing

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
扫码
拉您进交流群
GMT+8, 2026-2-7 20:00