【问题标题】:how to write a loop for finding median across columns如何编写一个循环来查找跨列的中位数
【发布时间】:2020-09-08 03:27:30
【问题描述】:

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

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 都是连续的非参数变量。

【问题讨论】:

  • 只是为了确认。你想要所有患者的中位数(所有样本的中位数)。或每位患者的中位数。 (每位患者 a、b、c 的中位数)
  • SO 不是免费的编码服务;使用dput 发布您的数据,这样我们就不必全部输入。然后分享您已经处理过的代码的精髓并提出您可能遇到的具体问题。请参阅here,了解如何制作可重现的示例。谷歌例如R data analysis with dplyr,你会发现很多有用的例子可以帮助你解决问题。
  • 每个帖子只问一个问题。还包括您尝试过但卡住或不起作用的代码。

标签: r loops median iqr


【解决方案1】:

您似乎希望我们为您完成初始探索性​​数据分析的所有步骤。在您的下一篇文章中,您应该首先展示您对可重现代码的问题,展示您尝试的结果,并就您的疑问提出具体问题,而不是要求这样的编码。也就是说,让我们看看你的问题:

您可以在循环中使用 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, quantile, 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[,i], 0.25, na.rm = na.rm)
                        Q3[i]<-quantile(x[,i], 0.75, na.rm = na.rm)
                        means[i]<-round(mean(x[,i], na.rm = na.rm), digits = digits)
                        SDs[i]<-round(sd(x[,i], 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[,i], "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 的 filter 和 group_by 函数。

【讨论】:

  • 啊,我的错。我对编码和这个论坛很陌生。感谢您的帮助!我是个菜鸟,甚至不知道可以使用 sapply,所以我一直在对中位数(dataframe$variable)进行编码并为每个变量复制粘贴。是的,我知道重复在编码中是不好的。我会尝试使用该功能。
  • 嗨,@han,很高兴为您提供帮助。如果您认为答案解决了您的问题,您可以使用“接受答案按钮”(答案的左上角)接受答案。接受和支持答案通常比在评论部分感谢更好。
【解决方案2】:

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

# creating your data

data = matrix (c(142,343,125,110,115,125,120,181,1,
  175,192,121,125,215,120,135,151,0,
  154,185,128,210,115,125,124,116,0,  
  170,215,215,110,125,110,145,205,1, 
  175,140,225,110,115,110,125,120,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)
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-20
    • 2019-08-07
    • 2011-02-07
    • 2018-03-09
    相关资源
    最近更新 更多