dplyr 提供的数据处理方式非常直观且强大,不仅可以处理单个列,也可以同时处理多列或多行。本文通过一个简单示例进行对比不同方式实现,从而让读者体会dplyr简单、强大的处理方式。
假设我们有三个学科的成绩,但由于分值范围不同,需要进行标准化处理。然后按行求平均值。
我们首先用R内置能力实现:
set.seed(12345)
data <-data.frame(chinese=runif(50,1,100),
math=runif(50,1,100),
english=runif(50,1,50))
head(data)
# chinese math english
#
# 1 72 96 15
# 2 88 83 31
# 3 76 32 49
# 4 89 22 31
# 5 46 74 27
# 6 17 50 45
我们首先生成三个学科的成绩。然后使用 scale 函数 对每列进行标准化;接着再用apply函数按行求平均;最后利用cbind函数绑定列:
z = sapply(data, scale)
# z = scale(data)
head(z)
# chinese math english
# [1,] 0.77 1.427 -0.98
# [2,] 1.29 0.983 0.14
# [3,] 0.90 -0.675 1.37
# [4,] 1.33 -1.005 0.14
# [5,] -0.13 0.676 -0.20
# [6,] -1.12 -0.079 1.12
means <- apply(z, 1, mean)
score <- cbind(z, means)
head(score)
这里也直接使用scale,其参数为数值矩阵,当然也可以使用sapply,其参数vector 或 list。
apply 函数第二个参数 MARGIN 为1 表示 按行执行,2 表示按列执行函数。
# install.packages("dplyr") # Install & load dplyr package
library("dplyr")
z <- data %>% mutate_each(funs(scale))
# head(z)
# Show in New Window
# chinese math english
# [1,] 0.77 1.427 -0.98
# [2,] 1.29 0.983 0.14
# [3,] 0.90 -0.675 1.37
# [4,] 1.33 -1.005 0.14
# [5,] -0.13 0.676 -0.20
# [6,] -1.12 -0.079 1.12
score <- z %>% mutate(means=rowMeans(z))
head(score)
# chinese math english means
# 1 0.77 1.427 -0.98 0.404
# 2 1.29 0.983 0.14 0.803
# 3 0.90 -0.675 1.37 0.533
# 4 1.33 -1.005 0.14 0.153
# 5 -0.13 0.676 -0.20 0.116
# 6 -1.12 -0.079 1.12 -0.024
首先使用mutate_each对每列执行scale函数,然后再使用mutate函数对每行执行rowMeans增加rowMeans函数生成means列。整个过程非常流程、简单、直接。
前面我们使用了R内置rowMeans函数,用于计算matrix 或 array 每行平均数。
语法如下:
rowMeans(x, na.rm = FALSE, dims = 1)
当然其他几个类似函数也可以:colMeans, rowSums, colSums.