简体   繁体   中英

R - Get a summary table containing specified percentile levels for a dataframe

I want to get a summary table that displays more than the typical descriptive statistics generated by the summary(x) function in R. For instance 10% percentile, 90% percentile. Other answers that I found online recommend ways that give the answers but not in a tabulated form.

I was looking for a way that would just add the specified percentile level in the summary table generated by the summary(x) function.

Here's example data:

df = data.frame("a"=seq(1,10), "b"=seq(10,100,10),
                "c"=letters[seq(1,10)], "d"=seq(5,95,10))

在此处输入图片说明

# generate data
df = data.frame("a"=seq(1,10), "b"=seq(10,100,10), "c"=letters[seq(1,10)], "d"=seq(5,95,10))

# filter numerical columns
ndf = Filter(is.numeric,df)
features = colnames(ndf)

# percentiles reqd
p_reqd = c(0,0.10,0.25,0.5,0.75,0.90,0.95,1)   # more percentile levels can be specified here
                                               # after adding/removing, adjust p_lev as well

# labels for specified percentiles + mean
p_lev = c('Min','10%','25%','50%','Mean','75%','90%','95%','Max')

# created empty dataframe with row names specified
final = data.frame(row.names = p_lev)

# loop
for (i in features) {
  x = ndf[,i]
  sm = data.frame("dStats" = quantile(x, p_reqd))
  final[1:which(rownames(final)=="50%"),i] = sm$dStats[1:which(rownames(sm)=="50%")]
  final[which(rownames(final)=="50%")+1,i] = round(mean(x),2)
  final[(which(rownames(final)=="50%")+2):nrow(final), i] = 
    sm$dStats[(which(rownames(sm)=="50%")+1):nrow(sm)]  
}

# custom summary table
final

在此处输入图片说明

There is also a dplyr and tidyr way of doing this.

df = data.frame("a"=seq(1,10), "b"=seq(10,100,10),
                "c"=letters[seq(1,10)], "d"=seq(5,95,10))
library(dplyr)
library(tidyr)
out <- df %>% summarise_if(is.numeric, .funs = list(
  "Min" = min, 
  "10%" = function(x)quantile(x, .1), 
  "25%" = function(x)quantile(x, .25), 
  "50%" = median, 
  "Mean" = mean, 
  "75%" = function(x)quantile(x, .75), 
  "90%" = function(x)quantile(x, .90), 
  "Max" = max)) %>% 
pivot_longer(cols=everything(), 
             names_pattern = "(.*)_(.*)", 
             names_to = c("var", "stat"), 
             values_to="vals") %>% 
  pivot_wider(names_from="var", 
              values_from="vals",
              id_cols="stat") %>% 
  as.data.frame()

rownames(out) <- out$stat
out <- out %>% select(-stat)
out
#          a     b    d
# Min   1.00  10.0  5.0
# 10%   1.90  19.0 14.0
# 25%   3.25  32.5 27.5
# 50%   5.50  55.0 50.0
# Mean  5.50  55.0 50.0
# 75%   7.75  77.5 72.5
# 90%   9.10  91.0 86.0
# Max  10.00 100.0 95.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM