如何按行统计数据框子集内不同值数量并生成最大值列
问题描述
我有如下的dataframe:
df = read.table(text="ID L1 L2 L3 L4 L5 L6 L7 L8 S1 S2 S3 S4 S5 S6 S7 S8 T1 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2 2 T2 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 T3 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 T4 0 0 0 1 0 0 0 0 0 1 2 2 1 1 1 1 T5 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 T6 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 T7 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 T8 0 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 T9 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 2", header=T, stringsAsFactors=F)
需要分别按行统计两个列子集(通过grep("^L",names(df))和grep("^S",names(df))筛选)中0、1、2的出现次数,然后新增两列,分别对应两个子集中出现次数最多的值。期望结果如下:
ID L S T1 0 2 T2 0 2 T3 0 2 T4 0 1 T5 0 2 T6 0 2 T7 0 2 T8 0 0 T9 0 2
解决方案
方法一:Base R实现
自定义函数计算每行的众数,再分别对L、S列组应用:
# 定义函数:获取向量中出现次数最多的元素 get_mode <- function(x) { tab <- table(x) names(tab)[which.max(tab)] |> as.integer() } # 计算L列组的行众数 df$L <- apply(df[, grep("^L", names(df))], 1, get_mode) # 计算S列组的行众数 df$S <- apply(df[, grep("^S", names(df))], 1, get_mode) # 提取目标结果 result <- df[, c("ID", "L", "S")] print(result)
方法二:Tidyverse(dplyr + tidyr)实现
通过数据重塑分组统计众数:
library(dplyr) library(tidyr) result <- df |> pivot_longer(cols = -ID, names_to = c("group", "num"), names_pattern = "(.)(.)") |> group_by(ID, group) |> count(value) |> slice_max(n, n = 1) |> select(-n) |> pivot_wider(names_from = group, values_from = value) |> arrange(ID) print(result)
内容的提问来源于stack exchange,提问作者user3354212
相关产品推荐
相关产品推荐

