为 R 中的数据帧列表获取一个 table 统计信息(最大、最小、IQR、...)
Get one table statistics (max, min, IQR, ...) for a list of data frames in R
我有几个数据框。
我需要在一个 table 中显示所有统计数据和四分位数间距 (IQR)。
不幸的是,summary
函数没有 return IQR。
另一方面,fivenum
returns IQR,但不能(?)应用于数据帧列表,我不需要中位数。
由于找不到合适的函数,自己写了一个如下:
removeXYcol <- function(df)
{
# removes coordinates
drops <- c("X","Y")
withoutXY<- df[,!(names(df) %in% drops)]
withoutXY
}
getStatsTable <- function(listOfDataFrames, df_names = NULL, digits_no = 2)
{
# returns table with statistics (together with IQR which is not returned by summary)
for (df in listOfDataFrames){
df_data <- unlist(removeXYcol(df))
minimum <- round(min(df_data,na.rm = TRUE),digits = digits_no)
maximum <- round(max(df_data, na.rm = TRUE),digits = digits_no)
average <- round(mean(df_data, na.rm = TRUE),digits = digits_no)
IQR_ <- round(IQR(df_data, na.rm = TRUE),digits = digits_no)
toReturn <- c(minimum, maximum, average, IQR_)
if (exists("myStats")) {
myStats <- rbind(myStats, toReturn)
} else {
myStats <- toReturn
}
}
colnames(myStats) <- c("minimum", "maximum", "average", "IQR")
if (is.null(df_names)) {
df_names <- seq(length(listOfDataFrames))
}
rownames(myStats) <- df_names
return(myStats)
}
但是我想知道是否有更简单的解决方案。
fivenum
采用向量,因此您必须 lapply
跨越列表,加上 lapply
跨越 data.frame,例如
lapply(list(mtcars, mtcars), function(df){lapply(df, fivenum)})
## [[1]]
## [[1]]$mpg
## [1] 10.40 15.35 19.20 22.80 33.90
##
## [[1]]$cyl
## [1] 4 4 6 8 8
## ...
另一种方法是 purrr::at_depth
,它允许您指定要迭代的列表级别:
purrr::at_depth(list(mtcars, mtcars), 2, fivenum)
## [[1]]
## [[1]]$mpg
## [1] 10.40 15.35 19.20 22.80 33.90
##
## [[1]]$cyl
## [1] 4 4 6 8 8
## ...
一个更复杂的版本 returns 一个格式更好的 data.frame 列表:
library(tidyverse)
list(mtcars, mtcars) %>%
map(gather, var, val) %>%
map(group_by, var) %>%
map(summarise,
val = list(fivenum(val)),
label = list(c('min', 'q1', 'med', 'q3', 'max'))) %>%
map(unnest) %>%
map(spread, label, val)
## [[1]]
## # A tibble: 11 × 6
## var max med min q1 q3
## * <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 am 1.000 0.000 0.000 0.0000 1.00
## 2 carb 8.000 2.000 1.000 2.0000 4.00
## 3 cyl 8.000 6.000 4.000 4.0000 8.00
## ...
我有几个数据框。
我需要在一个 table 中显示所有统计数据和四分位数间距 (IQR)。
不幸的是,summary
函数没有 return IQR。
另一方面,fivenum
returns IQR,但不能(?)应用于数据帧列表,我不需要中位数。
由于找不到合适的函数,自己写了一个如下:
removeXYcol <- function(df)
{
# removes coordinates
drops <- c("X","Y")
withoutXY<- df[,!(names(df) %in% drops)]
withoutXY
}
getStatsTable <- function(listOfDataFrames, df_names = NULL, digits_no = 2)
{
# returns table with statistics (together with IQR which is not returned by summary)
for (df in listOfDataFrames){
df_data <- unlist(removeXYcol(df))
minimum <- round(min(df_data,na.rm = TRUE),digits = digits_no)
maximum <- round(max(df_data, na.rm = TRUE),digits = digits_no)
average <- round(mean(df_data, na.rm = TRUE),digits = digits_no)
IQR_ <- round(IQR(df_data, na.rm = TRUE),digits = digits_no)
toReturn <- c(minimum, maximum, average, IQR_)
if (exists("myStats")) {
myStats <- rbind(myStats, toReturn)
} else {
myStats <- toReturn
}
}
colnames(myStats) <- c("minimum", "maximum", "average", "IQR")
if (is.null(df_names)) {
df_names <- seq(length(listOfDataFrames))
}
rownames(myStats) <- df_names
return(myStats)
}
但是我想知道是否有更简单的解决方案。
fivenum
采用向量,因此您必须 lapply
跨越列表,加上 lapply
跨越 data.frame,例如
lapply(list(mtcars, mtcars), function(df){lapply(df, fivenum)})
## [[1]]
## [[1]]$mpg
## [1] 10.40 15.35 19.20 22.80 33.90
##
## [[1]]$cyl
## [1] 4 4 6 8 8
## ...
另一种方法是 purrr::at_depth
,它允许您指定要迭代的列表级别:
purrr::at_depth(list(mtcars, mtcars), 2, fivenum)
## [[1]]
## [[1]]$mpg
## [1] 10.40 15.35 19.20 22.80 33.90
##
## [[1]]$cyl
## [1] 4 4 6 8 8
## ...
一个更复杂的版本 returns 一个格式更好的 data.frame 列表:
library(tidyverse)
list(mtcars, mtcars) %>%
map(gather, var, val) %>%
map(group_by, var) %>%
map(summarise,
val = list(fivenum(val)),
label = list(c('min', 'q1', 'med', 'q3', 'max'))) %>%
map(unnest) %>%
map(spread, label, val)
## [[1]]
## # A tibble: 11 × 6
## var max med min q1 q3
## * <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 am 1.000 0.000 0.000 0.0000 1.00
## 2 carb 8.000 2.000 1.000 2.0000 4.00
## 3 cyl 8.000 6.000 4.000 4.0000 8.00
## ...