如何编写一个循环来查找跨列的中位数
how to write a loop for finding median across columns
我有一个关于具有不同临床结果的肾移植患者的数据框(出于保密目的更改了数字。换句话说,我有这样的东西。
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 都是连续的非参数变量。
试试下面的代码。请注意,我没有考虑最后一列 (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)
})
您似乎希望我们为您完成初始探索性数据分析的所有步骤。在你的下一篇文章中,不要像这样要求编码,你应该首先用可重现的代码展示你的问题,展示你尝试的结果,并针对你的疑问提出具体问题。也就是说,让我们看看你的问题:
您可以在循环中使用 return 每列的中位数、均值、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 的过滤器和 group_by 函数。
我有一个关于具有不同临床结果的肾移植患者的数据框(出于保密目的更改了数字。换句话说,我有这样的东西。
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 都是连续的非参数变量。
试试下面的代码。请注意,我没有考虑最后一列 (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)
})
您似乎希望我们为您完成初始探索性数据分析的所有步骤。在你的下一篇文章中,不要像这样要求编码,你应该首先用可重现的代码展示你的问题,展示你尝试的结果,并针对你的疑问提出具体问题。也就是说,让我们看看你的问题:
您可以在循环中使用 return 每列的中位数、均值、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 的过滤器和 group_by 函数。