【发布时间】:2016-07-29 17:29:58
【问题描述】:
假设我在 R 工作区中有如下数据框
a b c d
s 1 2 3 4
t 2 4 5 6
u 1 9 7 6
v 9 2 3 4
w 3 2 0 2
x 3 2 0 9
y 9 2 4 3
z 8 3 4 5
如何在不使用 R 中的 FOR LOOPS 的情况下自动提取矩阵每列的范围、平均值、标准差、中值、最大值和最小值?可以用apply/sapply/lapply吗??
【问题讨论】:
假设我在 R 工作区中有如下数据框
a b c d
s 1 2 3 4
t 2 4 5 6
u 1 9 7 6
v 9 2 3 4
w 3 2 0 2
x 3 2 0 9
y 9 2 4 3
z 8 3 4 5
如何在不使用 R 中的 FOR LOOPS 的情况下自动提取矩阵每列的范围、平均值、标准差、中值、最大值和最小值?可以用apply/sapply/lapply吗??
【问题讨论】:
对于这种情况有几个不同的选项。其他人提到了apply 函数,但apply 在矩阵上工作,如果给定一个数据框,它将首先将其转换为矩阵,然后再应用该函数。对于示例数据框,这不是问题(但首先转换效率会很低),但如果与包含非数字列的数据框一起使用,则可能会导致问题。
最好使用sapply,它直接作用于列表(数据框是列表的一种形式):
> sapply(mtcars, function(x) c(mean(x), median(x), sd(x)))
mpg cyl disp hp drat wt qsec
[1,] 20.090625 6.187500 230.7219 146.68750 3.5965625 3.2172500 17.848750
[2,] 19.200000 6.000000 196.3000 123.00000 3.6950000 3.3250000 17.710000
[3,] 6.026948 1.785922 123.9387 68.56287 0.5346787 0.9784574 1.786943
vs am gear carb
[1,] 0.4375000 0.4062500 3.6875000 2.8125
[2,] 0.0000000 0.0000000 4.0000000 2.0000
[3,] 0.5040161 0.4989909 0.7378041 1.6152
您可以通过更改上面的函数来计算每列所需的任何函数。
您可能还想考虑 dplyr 包,它具有执行此类操作的功能,其形式可能更具可读性,并且可以以更简单的方式适应更复杂的情况。
> library(dplyr)
> mtcars %>% summarise_each(funs(mean,median,sd))
mpg_mean cyl_mean disp_mean hp_mean drat_mean wt_mean qsec_mean vs_mean
1 20.09062 6.1875 230.7219 146.6875 3.596563 3.21725 17.84875 0.4375
am_mean gear_mean carb_mean mpg_median cyl_median disp_median hp_median
1 0.40625 3.6875 2.8125 19.2 6 196.3 123
drat_median wt_median qsec_median vs_median am_median gear_median
1 3.695 3.325 17.71 0 0 4
carb_median mpg_sd cyl_sd disp_sd hp_sd drat_sd wt_sd
1 2 6.026948 1.785922 123.9387 68.56287 0.5346787 0.9784574
qsec_sd vs_sd am_sd gear_sd carb_sd
1 1.786943 0.5040161 0.4989909 0.7378041 1.6152
> mtcars %>% summarise_each(funs(mean,median,sd)) %>%
matrix(nrow=ncol(mtcars), dimnames=list(names(mtcars), c('Mean','Median','SD')))
Mean Median SD
mpg 20.09062 19.2 6.026948
cyl 6.1875 6 1.785922
disp 230.7219 196.3 123.9387
hp 146.6875 123 68.56287
drat 3.596563 3.695 0.5346787
wt 3.21725 3.325 0.9784574
qsec 17.84875 17.71 1.786943
vs 0.4375 0 0.5040161
am 0.40625 0 0.4989909
gear 3.6875 4 0.7378041
carb 2.8125 2 1.6152
【讨论】:
apply(df, 2, summary)
a b c d
#Min. 1.00 2.00 0.00 2.000
#1st Qu. 1.75 2.00 2.25 3.750
#Median 3.00 2.00 3.50 4.500
#Mean 4.50 3.25 3.25 4.875
#3rd Qu. 8.25 3.25 4.25 6.000
#Max. 9.00 9.00 7.00 9.000
【讨论】:
sapply(df, summary)。要获取范围,请使用sapply(df, range)。
sapply 这样做了:)
summary 函数只是一个示例,以便向 OP 展示如何遍历列
fun <- c('mean', 'sd', 'median', 'min', 'max')
sapply(fun, function(x) apply(dff, 2, match.fun(x)))
你会得到这样的输出,
mean sd median min max
a 4.500 3.545621 3.0 1 9
b 3.250 2.434866 2.0 2 9
c 3.250 2.375470 3.5 0 7
d 4.875 2.167124 4.5 2 9
【讨论】: