[R语言实战笔记] 第5章 高级数据管理

本章内容

数学和统计函数
字符处理函数
循环和条件执行
自编函数
数据整合与重塑

5.1 一个数据处理难题

均值和标准差相去甚远,求平均值没有意义。变换为可比较的单元。巧妙利用数值和字符处理函数。

5.2 数值和字符处理函数

数据处理基石的函数:数值(数学、统计、概率)函数和字符处理函数,应用于矩阵和数据框。

5.2.1 数学函数

对数据做变换是这些函数的一个主要用途。当应用于数值向量、矩阵或数据框时,会作用于每一个独立的值。[P86]

abs(x) # 绝对值
sqrt(x) # 平方根
ceiling(x) # 不小于x的最小整数
floor(x) # 不大于x的最大整数
log(x, base = n) # 对x取以n为底的对数
log(x)
log10(x)
log(10)
log10(10)
exp(x) # 指数函数

5.2.2 统计函数

许多函数都有影响输出结果的可选参数。比如:
y <- mea(x)
z <- mean(x, trim = 0.05, na.rm = TRUE)
y提供了算术平均数,z提供了截尾平均数,即丢弃了最大5%和最小5%的数据和所有缺失值后的算术平均数。

mean(x)
median(x)
sd(x)
var(x)
mad(x)
quantile(x, probs)
range(x)
sum(x)
diff(x, lag = n)
min(n)
max(x)
scale(x, center = TRUE, scale = TRUE) #为数据对象x按列进行中心化或标准化

##均值和标准差的计算
x <- c(1:8)
#简洁的方式
mean(x)
sd(x)
#冗长的方式
n <- length(x)
meanx <- sum(x)/n
css <- sum((x - meanx)^2)
sdx <- sqrt(css / (n-1))
meanx
sdx

数据的标准化
默认情况下,函数scale()对矩阵或数据框的指定进行均值为0、标准差为1的标准化:
newdata <- scale(mydata)
要对每一列进行任意均值和标准差的标准化,可以使用如下的代码:
newdata <- scale(mydata)*SD + M
其中的M是想要的均值,SD为想要的标准差。在非数值型的列上使用scale()函数将会报错。要 对指定列而不是整个矩阵或数据框进行标准化,你可以使用这样的代码:
newdata <- transform(mydata, myvar = scale(myvar)*10 +50)
此句将变量myvar标准化为均值50、标准差为10的变量。

5.2.3 概率函数

概率函数通常用来生产特征已知的模拟数据,以及在用户编写的统计函数中计算概率值。


image.png
  1. 设定随机数种子
    在每次生成伪随机数的时候,函数都会使用一个不同的种子,因此也会产生不同的结果。set.seed()
runif(5) #重复两次
set.seed(1234)
runif(5)
  1. 生成多元正态数据
    在模拟研究和蒙特卡洛方法中,你经常要获取来自给定均值向量和协方差阵的多元正态分布的数据。MASS包中的mvnorm()函数可以让这个问题变得很容易。
    mvnorm(n, mean, siga)

5.2.4 字符处理函数

字符处理函数可以从文本型数据中抽取信息,或者为打印输出和生成报告重设文本的格式。

image.png

image.png

正则表达式(英语:Regular Expression,常简写为regex、regexp或RE),又称正则表示式正则表示法规则表达式常规表示法,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串、。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

5.2.5 其他实用函数

下列函数对于数据管理和处理同样非常实用。

length(x) #对象x的长度
seq(from, to , by) #生成一个序列
rep(x, n) #将x重复n次
cut(x, n) #将连续型变量x分割为有着n个水平的因子
#使用选项ordered_result = TRUE以创建一个有序型因子
pretty(x, n) #创建美观的分割点。通过选取n+1个等间距的取整值,将一个连续型变量x分割为n个 区间。绘图中常用
cat(..., file = "filename", append  = F) #连接...中的对象,并将其输出到屏幕上或文件中(如果声明了一个的话)

注:\n表示新行,\t表示制表符,\'表示单引号,\b表示退格。(键入?quotes了解更多)

5.2.6 将函数应用于矩阵和数据框

R函数的诸多有趣特性之一,就是它们可以应用到一系列的数据对象上,包括标量、向量、 矩阵、数组和数据框。

> a <- 5
> sqrt(5)
[1] 2.236068
> b <- c(1.243, 5.654, 2.99)
> round(b)
[1] 1 6 3
> c <- matrix(runif(12), nrow = 3)
> c
          [,1]       [,2]        [,3]      [,4]
[1,] 0.7699015 0.61823636 0.820176206 0.6085722
[2,] 0.7128397 0.05048374 0.009614496 0.7698180
[3,] 0.3033602 0.04321880 0.102491504 0.6605425
> log(c)
           [,1]       [,2]       [,3]       [,4]
[1,] -0.2614926 -0.4808844 -0.1982361 -0.4966397
[2,] -0.3384987 -2.9861040 -4.6444833 -0.2616011
[3,] -1.1928344 -3.1414796 -2.2779754 -0.4146939
> mean(c) #矩阵c求均值的结果为一个标量(0.444)。函数mean()求得的是 矩阵中全部12个元素的均值。
[1] 0.4557713

apply()函数,可将一个任意函数“应用”到矩阵、数组、数据框的任何维度上。
apply(x, MARGIN, FUN, ...)
MARGIN=1表示行,MARGIN=2表示列。

> mydata <- matrix(rnorm(30), nrow = 6) #生成了一个包含正态随机数的6×5矩阵
> mydata
           [,1]       [,2]       [,3]        [,4]       [,5]
[1,] -0.7826228 -1.1176011 -0.3271264 -0.80825957 -0.9345593
[2,]  0.5092959  0.2340028 -2.2632252 -0.51215317  0.6303857
[3,] -1.4899391  0.3161516  0.2855605 -1.80397184  0.7607600
[4,] -0.3191793  0.3707686  0.9684286  0.04062997 -0.5116228
[5,] -0.2379111  0.8775886  0.8673066  2.63601650  1.0019075
[6,]  1.6186229 -1.7683235  1.3781350 -1.61599923 -0.3833922
> apply(mydata, 1, mean) #计算6行的均值
[1] -0.7940338 -0.2803388 -0.3862878  0.1098050  1.0289816 -0.1541914
> apply(mydata, 2, mean) #计算5列的均值
[1] -0.11695557 -0.18123552  0.15151317 -0.34395622  0.09391315
> apply(mydata, 2, mean, trim = 0.2) #计算每列的截尾均值
[1] -0.20760431 -0.04916954  0.44854232 -0.72394550  0.12403268

5.3 数据处理难题的一套解决方案

见P96。
瞧!小事一桩!

5.4 控制流

  • 语句(statement)是一条单独的R语句或一组复合语句。(包含在花括号{ } 中的一组R语 句,使用分号分隔);
  • 条件(cond)是一条最终被解析为真(TRUE)或假(FALSE)的表达式;
  • 表达式(expr)是一条数值或字符串的求值语句。
  • 序列(seq)是一个数值或字符串函数。

5.4.1 重复和循环

for结构
for循环重复地执行一个语句,直到某个变量的值不再包含在序列seq中为止。
for (var in seq) statement

for (i in 1:10) print("Hello")

while结构
while循环重复地执行一个语句,直到条件不为真为止。
while (cond) statement

> i <- 10
> while(i > 0) {print("Hello"); i <- 1-1}
[1] "Hello"
> while(i > 0) {print("Hello"); i <- i-1}
> i <- 10
> while(i > 0) {print("Hello"); i <- i-1}
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"

5.4.2 条件执行

在条件执行结构中, 一条或一组语句仅在满足一个指定条件时执行。 条件执行结构包括 if-else、ifelse和switch。

  • if-else结构
    if (cond) statement
    if (cond) statement else statement2
  • ifelse结构
    ifelse (cond, statement1, statement2)
  • swtich结构
    switch (expr, ...)
> feelings <- c("sad","afraid")
> for(i in feelings) print(
+   switch(i,
+          happy = "I am glad you are happy",
+          afraid = "There is nothing to fear",
+          sad = "Cheer up",
+          angry = "Calm down now"
+          )
+ )
[1] "Cheer up"
[1] "There is nothing to fear"

5.5 用户自编函数

一个函数的结构看起来大致如此:
myfunction <- function(arg1, arg2, ...) {statements return(object)}
假设你想编写一个函数,用来计算数据对象的集中趋势和散布情况。此函数应当可以选择性地给出参数统计量(均值和标准差)非参数统计量(中位数和绝对中位差)。结果应当以一个 含名称列表的形式给出。另外,用户应当可以选择是否自动输出结果。除非另外指定,否则此函 数的默认行为应当是计算参数统计量并且不输出结果。

mystats <- function(x, parametric = T, print = F) {
  if (parametric) {
    center <- mean(x); spread <- sd(x)
  } else {
    center <- median(x); spread <- mad(x)
  }
  if (print & parametric) {
    cat("Mean = ", center, "\n", "SD = ", spread, "\n")
  } else if (print & !parametric) {
    cat("Median=", center, "\n", "MAD=", spread, "\n")
  }
  results <- list(center = center, spread = spread)
  return(results)
}

set.seed(1234)
x <- rnorm(500)
y <- mystats(x)
y <- mystats(x, parametric = F, print = T)

5.6 整合与重构

R中提供了许多用来整合(aggregate)重塑(reshape)数据的强大方法。本节主要使用mtcars数据集。请参阅help(mtcars)

5.6.1 转置

t()反转行和列

5.6.2 整合数据

在R中使用一个或多个by变量和一个预先定义好的函数来折叠(collapse)数据是比较容易的。
aggregate(x, by, FUN)
其中x是待折叠的数据对象,by是一个变量名组成的列表,这些变量将被去掉以形成新的观测, 而FUN则是用来计算描述性统计量的标量函数,它将被用来计算新观测中的值。

> options(digits = 3)
> attach(mtcars)
> aggdata <- aggregate(x = mtcars, by = list(cyl, gear), FUN = mean, na.rm = T)
> aggdata
  Group.1 Group.2  mpg cyl disp  hp drat   wt qsec  vs   am gear carb
1       4       3 21.5   4  120  97 3.70 2.46 20.0 1.0 0.00    3 1.00
2       6       3 19.8   6  242 108 2.92 3.34 19.8 1.0 0.00    3 1.00
3       8       3 15.1   8  358 194 3.12 4.10 17.1 0.0 0.00    3 3.08
4       4       4 26.9   4  103  76 4.11 2.38 19.6 1.0 0.75    4 1.50
5       6       4 19.8   6  164 116 3.91 3.09 17.7 0.5 0.50    4 4.00
6       4       5 28.2   4  108 102 4.10 1.83 16.8 0.5 1.00    5 2.00
7       6       5 19.7   6  145 175 3.62 2.77 15.5 0.0 1.00    5 6.00
8       8       5 15.4   8  326 300 3.88 3.37 14.6 0.0 1.00    5 6.00

在使用aggregate()函数的时候,by中的变量必须在一个列表中(即使只有一个变量)。

5.6.3 reshape2包

reshape包是一套重构和整合数据集的绝妙的万能工具。有点难度!
数据融合(melt)重铸(cast)

  • 融合
> ID = c("1", "1", "2", "2")
> Time = c("1", "2", "1","2")
> X1 = c(5, 3, 6, 2)
> X2 = c(6, 5, 1, 4)
> mydata = data.frame(ID, Time, X1, X2)
> mydata
  ID Time X1 X2
1  1    1  5  6
2  1    2  3  5
3  2    1  6  1
4  2    2  2  4
> library(reshape2)
> md <- melt(mydata, id = c("ID", "Time")) 
> md
  ID Time variable value
1  1    1       X1     5
2  1    2       X1     3
3  2    1       X1     6
4  2    2       X1     2
5  1    1       X2     6
6  1    2       X2     5
7  2    1       X2     1
8  2    2       X2     4

必须指定要唯一确定每个测量所需的变量(ID和Time),而表示测量变量名的变量(X1 或X2)将由程序为你自动创建。

  • 重塑
    newdata <- dcast(md, formula, fun.aggregate)
    其中的md为已融合的数据,formula描述了想要的最后结果,而FUN是(可选的)数据整合函数。
    image.png

5.7 小结

处理数据的数学、统计和概率函数
函数应用于向量、矩阵和数据框
控制流结构:循环重复,条件
自定义函数
折叠、整合以及重构数据

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,454评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,553评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,921评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,648评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,770评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,950评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,090评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,817评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,275评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,592评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,724评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,409评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,052评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,815评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,043评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,503评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,627评论 2 350