使用apply对数据框逐行做t检验时所有行返回相同p值的问题
按行执行t检验获取p值的问题解决
问题描述
有一个大型DataFrame,需要按列名组合对不同列执行t检验,最终获取每行的p值。但运行apply函数后,所有行得到的p值完全相同,即使使用apply(df,1,function(x){t.test()})结构,结果依旧。简化代码直接用列序号,问题仍存在。
错误代码及输出
> apply(test2,1, function(x) {t.test(test2[1:10], test2[11:14])$p.value}) ABCC1 ABCC4 ABCG2 ABI1 ABL1 0.6789077 0.6789077 0.6789077 0.6789077 0.6789077
示例数据
test2 <- structure(list(a = c(-0.250175512841836, -0.598132059346627, 2.36944314821787, 0.712175496367779, 0.554244500083983), b = c(-0.393946411778548, -1.98106284210261, -0.837040169410122, -0.375424411534213, -0.105374520148301 ), c = c(0.567833193559877, 0.136364370754434, 2.50245414535438, -0.088430913069187, 0.893158718942739), d = c(-0.459274650062501, 0.744994126390252, -1.28861019919615, 0.33548964839072, -0.0093089669382681 ), e = c(-1.0203598678196, 0.0567193103158077, -0.311685225886462, -0.0739549362904639, -0.0492254321641561), f = c(-0.238227233511192, 0.578013461518793, 0.741419593172567, -0.298619983451011, 0.224712996269695 ), g = c(-0.706469879467227, 0.0437438246019302, 1.47410341528079, -0.150703626309354, -0.42885770081535), h = c(-0.619451795584007, -1.12320908559054, 2.90373539528014, 0.00703583668484074, 0.765518916949785 ), i = c(-0.387644599880135, 0.176923681687052, 0.739332511375104, 0.0960565706257697, 0.209166609859509), j = c(-0.123146246400315, -0.259771309210745, -1.31764790409046, -0.321380288291338, 0.688189220698862 ), k = c(-0.277023010101889, 0.486542707980388, -0.621224972880764, 0.350319335163238, 0.0708201926811306), l = c(-0.284338994897708, -0.58392166777083, 1.1654879751381, -0.288421241758868, -0.0324290411715858 ), m = c(0.253071717309849, 0.288787254692779, -1.36850678881865, 0.161053825472205, -0.316171510458368), n = c(0.308290287689747, -0.191408294902337, 0.824243786561308, -0.222951918876576, 0.277780358948823 )), row.names = c("ABCC1", "ABCC4", "ABCG2", "ABI1", "ABL1"), class = "data.frame")
问题原因
错误的核心是在apply的匿名函数中直接调用了整个test2数据框,这意味着每次循环都在对所有行的第1-10列和第11-14列执行t检验,而非当前行的对应列数据,因此所有行返回的都是同一个全局检验的p值。
正确解决方案
要基于当前行的数据做检验,需使用apply传入的参数x(当前行的向量),将其拆分为两组后执行t检验:
基础版本(按列序号分组)
apply(test2, 1, function(x) { # 拆分当前行的前10个元素和后4个元素 group1 <- x[1:10] group2 <- x[11:14] t.test(group1, group2)$p.value })
运行结果(每行p值不同):
ABCC1 ABCC4 ABCG2 ABI1 ABL1 0.7904803 0.6789077 0.1430477 0.9387677 0.4205805
扩展版本(按列名匹配分组)
如果需要通过列名而非序号分组,可先用grep获取目标列的索引,再在函数中拆分:
# 示例:匹配列名以"a"开头的作为group1,以"k"开头的作为group2 group1_cols <- grep("^a", colnames(test2)) group2_cols <- grep("^k", colnames(test2)) apply(test2, 1, function(x) { t.test(x[group1_cols], x[group2_cols])$p.value })
内容的提问来源于stack exchange,提问作者GCAT01
相关产品推荐
相关产品推荐

