如何编写循环以查找各列的中位数

问题描述

我有一个关于具有不同临床结局的肾脏移植患者的数据框(出于保密目的更改了数字。换句话说,我有这样的东西。

Patient        eGFR1m cr1m  alb1m  cr3m   eGFR3m   alb3m  cr12m eGFR12m   diseased
A              142    343     125   110     115     125     120   181        1
B              175    192     121   125     215     120     135   151        0
C              154    185     128   210     115     125     124   116        0  
D              170    215     215   110     125     110     145   205        1 
E              175    140     225   110     115     110     125   120        0  

这是简化版。我有很多结果,所以我想创建一个循环来计算R中每一列的中位数和iqr

另一件事是,我需要该队列的中位数,以及患病组和未患病组的中位数作为比较。疾病结局以二进制,非连续变量的形式收集。每个月的eGFR,cr,​​alb都是连续的非参数变量。

解决方法

您似乎希望我们为您完成初始探索性​​数据分析的所有步骤。在下一个发布中,您不应该像这样请求编码,而是应该首先显示可再现代码的问题,显示尝试的结果,并提出有关疑问的特定问题。也就是说,让我们看看您的问题:

您可以使用Apply循环来为每一列返回中位数,均值,Q1和Q3。

sapply(yourdataframe,median) #will return a vector with the medians of every column

类似地,

sapply(yourdataframe,quantile,0.25) #will return a vector with all the first quartiles
sapply(yourdataframe,0.75) #will return a vector with all the third quartiles

您可能想编写一个函数,将所有函数集成在一个调用中,如下所示:


descriptive<-function(x=data.frame(),digits=2,na.rm=TRUE,normality_test="shapiro"){
        library(stats)
        is.normal<-character()
        medians<-numeric()
        Q1<-numeric()
        Q3<-numeric()
        means<-numeric()
        SDs<-numeric()
        output<-character()
        for (i in seq_along(x)){
                if (is.numeric(x[,i])){
                        medians[i]<-median(x[,i],na.rm = na.rm)
                        Q1[i]<-quantile(x[,0.25,na.rm = na.rm)
                        Q3[i]<-quantile(x[,0.75,na.rm = na.rm)
                        means[i]<-round(mean(x[,na.rm = na.rm),digits = digits)
                        SDs[i]<-round(sd(x[,na.rm=TRUE),digits = digits)
                        if (normality_test=="shapiro"){
                                p.value<-shapiro.test(x[,i])$p.value
                        } else if (normality_test=="ks"){
                                p.value<-ks.test(x[,"pnorm",means[i],SDs[i])$p.value
                        }
                        if (p.value<=0.05){
                                is.normal[i]<-FALSE
                                output[i]<-paste0(medians[i]," (",Q1[i],"-",Q3[i],")")
                        }else{
                                is.normal[i]<-TRUE
                                output[i]<-paste0(means[i]," +-",SDs[i])
                        }
                }else  {
                        is.normal[i]<-NA
                        means[i]<-NA
                        medians[i]<-NA
                        Q1[i]<-NA
                        Q3[i]<-NA
                        SDs[i]<-NA
                        output[i]<-NA
                }
        }      
        
        df<-data.frame(rbind( "normal distr"=is.normal,"median"=medians,"Q1"=Q1,"Q3"=Q3,"mean"=means,"SD"=SDs,"output"=output))
        names(df)<-colnames(x)
        df
}

例如:

> descriptive(iris,normality_test="shapiro")
              Sepal.Length Sepal.Width   Petal.Length   Petal.Width Species
normal distr         FALSE        TRUE          FALSE         FALSE    <NA>
median                 5.8           3           4.35           1.3    <NA>
Q1                     5.1         2.8            1.6           0.3    <NA>
Q3                     6.4         3.3            5.1           1.8    <NA>
mean                  5.84        3.06           3.76           1.2    <NA>
SD                    0.83        0.44           1.77          0.76    <NA>
output       5.8 (5.1-6.4) 3.06 +-0.44 4.35 (1.6-5.1) 1.3 (0.3-1.8)    <NA>

有几种方法可以根据分类值对数据进行子集分析,检查dplyr的过滤器和group_by函数。

,

尝试以下代码。请注意,我没有考虑最后一列(Diseased),因为中位数和IQR对离散变量没有意义。

# creating your data

data = matrix (c(142,343,125,110,115,120,181,1,175,192,121,215,135,151,154,185,128,210,124,116,170,145,205,140,225,0),ncol=9,byrow = TRUE)

colnames(data) <- c('eGFR1m','cr1m','alb1m','cr3m','eGFR3m','alb3m','cr12m','eGFR12m','Diseased')
rownames(data) <- LETTERS[1: nrow(data)]

# IQR and median for each column

apply(data[,-ncol(data)],2,function(x){
  Median = median(x,na.rm = TRUE)
  IQR = IQR(x,na.rm = TRUE)
  c(Median = Median,IQR = IQR)
})