基于数据框定义生物样本重复并计算统计量的方法问询
生物重复组的统计量计算问题
原始数据
你的数据框结构如下:
NAME VAL_1 VAL_2 Natural 2937,5 4082,5 Natural 3128 5347,5 Sus1 6176 7735,5 Sus1 8221 13793 Sus2 40961 68087 Sus2 6686 91341
需求是:按NAME列的相同值识别生物重复组,为每组计算均值并添加到新列,最终得到类似如下的结果:
| NAME | VAL_1 | AVERAGE_1 | VAL_2 | AVERAGE_2 | | Natural | 2937,5 | 3032,7 | 4082,5 | 4715,0 | | Natural | 3128,0 | 3032,7 | 5347,5 | 4715,0 |
问题解答
1. 正则匹配是不是定义重复组的最优方法?
绝对不是。原因有两点:
- 误匹配风险:你用
^Natural的正则会匹配所有以Natural开头的字符串(比如Natural1),完全违背了“只有NAME完全相同才是重复组”的逻辑; - 扩展性差:如果
NAME列有大量不同分组,你需要为每个分组写一条正则,操作繁琐且极易出错。
2. 替代方法:按NAME精确分组计算均值
核心思路是按NAME列的精确值分组,再将组内均值映射到每一行,以下是两种主流数据分析工具的实现:
方法一:R语言(dplyr或基础R)
首先需要处理数据格式:原数据中的逗号是小数点分隔符,需先转换为数值类型,再计算均值。
用dplyr实现(推荐)
# 读取数据 df <- read.table(text = "NAME VAL_1 VAL_2 Natural 2937,5 4082,5 Natural 3128 5347,5 Sus1 6176 7735,5 Sus1 8221 13793 Sus2 40961 68087 Sus2 6686 91341", header = TRUE, stringsAsFactors = FALSE) # 转换逗号为小数点,转为数值类型 df$VAL_1 <- as.numeric(gsub(",", ".", df$VAL_1)) df$VAL_2 <- as.numeric(gsub(",", ".", df$VAL_2)) # 分组计算均值并添加新列 library(dplyr) df_result <- df %>% group_by(NAME) %>% mutate( AVERAGE_1 = mean(VAL_1), AVERAGE_2 = mean(VAL_2) ) %>% ungroup() # 可选:将小数点转回逗号,匹配原数据格式 df_result <- df_result %>% mutate( across(c(VAL_1, VAL_2, AVERAGE_1, AVERAGE_2), ~ sprintf("%.1f", .) %>% gsub("\\.", ",", .)) )
用基础R的ave函数实现
# 先完成数值转换(同上) df$VAL_1 <- as.numeric(gsub(",", ".", df$VAL_1)) df$VAL_2 <- as.numeric(gsub(",", ".", df$VAL_2)) # 直接添加均值列 df$AVERAGE_1 <- ave(df$VAL_1, df$NAME, FUN = mean) df$AVERAGE_2 <- ave(df$VAL_2, df$NAME, FUN = mean) # 可选:转回逗号格式 df[ , c("VAL_1", "VAL_2", "AVERAGE_1", "AVERAGE_2")] <- lapply( df[ , c("VAL_1", "VAL_2", "AVERAGE_1", "AVERAGE_2")], function(x) sprintf("%.1f", x) %>% gsub("\\.", ",", .) )
方法二:Python(pandas)
import pandas as pd # 读取数据 df = pd.read_table( text="NAME VAL_1 VAL_2\nNatural 2937,5 4082,5\nNatural 3128 5347,5\nSus1 6176 7735,5\nSus1 8221 13793\nSus2 40961 68087\nSus2 6686 91341", sep="\\s+" ) # 转换逗号为小数点,转为数值类型 df[["VAL_1", "VAL_2"]] = df[["VAL_1", "VAL_2"]].replace(",", ".", regex=True).astype(float) # 分组计算均值并添加新列 df[["AVERAGE_1", "AVERAGE_2"]] = df.groupby("NAME")[["VAL_1", "VAL_2"]].transform("mean") # 可选:转回逗号格式 df[["VAL_1", "VAL_2", "AVERAGE_1", "AVERAGE_2"]] = df[["VAL_1", "VAL_2", "AVERAGE_1", "AVERAGE_2"]].applymap( lambda x: "{:.1f}".format(x).replace(".", ",") )
内容的提问来源于stack exchange,提问作者Someone_1313
相关产品推荐
相关产品推荐

