关于r:R语言之基本包

5次阅读

共计 5993 个字符,预计需要花费 15 分钟才能阅读完成。

文章和代码曾经归档至【Github 仓库:https://github.com/timerring/dive-into-AI】或者公众号【AIShareLab】回复 R 语言 也可获取。

用 R 根本包

在理论的数据分析中,剖析者往往须要破费大量的精力在数据的筹备上,将数据转换为剖析所须要的模式。遗憾的是,大多数统计学教材很少波及这一重要问题。整顿数据是统计学的工作之一。咱们开始关注 R 中最罕用的数据格式——数据框的基本操作。咱们将首先应用根本包解决数据框。

先加载 epiDisplay 包里的一个小型数据集 Familydata

library(epiDisplay)
data("Familydata")

1. 查看数据框里的内容

如果数据框较小,比方本例(只有 6 个变量,11 条记录),只需输出数据框名即可查看其全部内容,这等价于调用函数 print() 显示对象的内容。

# 输出数据框名即可查看其全部内容,这等价于调用函数 print( ) 显示对象的内容。Familydata
# 用函数 `head( )` 只显示其前几行
head(Familydata)
# 用函数 `tail( )` 显示其最初几行
tail(Familydata)
# 能够加参数指定到底几行
tail(Familydata,7) # 显示尾 7 行

# 列出所有变量名(列名)names(Familydata)

另一个能够用来不便地摸索数据框构造的函数是 str()

str(Familydata)

# ============== 显示后果 =============
# 首先给出了对象的类型(这里是数据框“data.frame”)、观测数和变量的个数;'data.frame':    11 obs. of  6 variables:
# 接着给出了数据框中每个变量的变量名和类型,以及变量的前几个取值
 $ code : chr  "K" "J" "A" "I" ...
 $ age  : int  6 16 80 18 69 72 46 42 58 47 ...
 $ ht   : int  120 172 163 158 153 148 160 163 170 155 ...
 $ wt   : int  22 52 71 51 51 60 50 55 67 53 ...
 $ money: int  5 50 100 200 300 500 500 600 2000 2000 ...
 # 对于因子型变量还给出了因子的程度;$ sex  : Factor w/ 2 levels "F","M": 1 2 2 1 1 1 1 1 2 1 ...
 # 最初给出了数据框的一些属性:# 数据标签(“datalabel”)- attr(*, "datalabel")= chr "Anthropometric and financial data of a hypothetical family"
 - # 数据建设工夫(“time.stamp”)- attr(*, "time.stamp")= chr "23 Nov 2006 17:15"
 - attr(*, "formats")= chr [1:6] "%9s" "%8.0g" "%8.0g" "%8.0g" ...
 - attr(*, "types")= int [1:6] 128 98 105 98 105 108
 # 变量标签(“var.labels”)- attr(*, "val.labels")= chr [1:6] """" """" ...
 - attr(*, "var.labels")= chr [1:6] """Age(yr)" "Ht(cm.)" "Wt(kg.)" ...
 # 版本号(“version”)- attr(*, "version")= int 7
 - attr(*, "label.table")=List of 6
  ..$ sex1: Named num [1:2] 1 2
  .. ..- attr(*, "names")= chr [1:2] "F" "M"
  ..$     : NULL
  ..$     : NULL
  ..$     : NULL
  ..$     : NULL
  ..$     : NULL

这些属性能够加强用户对数据集的了解。要想显示数据框属性的全副信息,能够应用 attributes() 函数,该函数的输入是一个列表。

attributes(Familydata)
# ================== 输入 ======================
$names
'code''age''ht''wt''money''sex'
$row.names
1234567891011
$class
'data.frame'
$datalabel
'Anthropometric and financial data of a hypothetical family'
$time.stamp
'23 Nov 2006 17:15'
$formats
'%9s''%8.0g''%8.0g''%8.0g''%8.0g''%8.0g'
$types
1289810598105108
$val.labels
'''''''''''sex1'
$var.labels
'''Age(yr)''Ht(cm.)''Wt(kg.)''Pocket money(B.)'''
$version
7
$label.table
$sex1
F1M2
[[2]]
NULL
[[3]]
NULL
[[4]]
NULL
[[5]]
NULL
[[6]]
NULL

也能够批改和自定义这些属性。例如,从下面的输入能够看到,第一个变量和最初一个变量没有定义标签。当初为这两个变量增加标签:

attr(Familydata, "var.labels")[1] <- "Identification number"
attr(Familydata, "var.labels")[6] <- "Gender"
attributes(Familydata)$var.labels
# 'Identification number''Age(yr)''Ht(cm.)''Wt(kg.)''Pocket money(B.)''Gender'

给变量增加标签能帮忙咱们更好地了解变量的含意。此外,前面用到的 epiDisplay 包里有些函数的输入还能间接应用这些变量标签。

2. 选取数据框的子集

与矩阵相似,咱们能够用索引下标的形式选取数据框的子集。

# 抉择数据框 Familydata 的第 3 列
Familydata[, 3]
# 也能够应用 $ 变量名的形式
Familydata$ht

# 要提取一个以上的变量,能够应用变量的索引号或名字。例如,只显示变量 ht、wt 和 sex 的前 3 条记录,能够输出:Familydata[1:3, c(3, 4, 6)]
# 等价于
Familydata[1:3, c("ht", "wt", "sex")]

下标中的索引还能够是一个条件语句。例如,要抉择性别为女性的数据,能够输出:

Familydata[Familydata$sex == "F",] # 留神逗号跟双等号

另一种抉择数据框的子集的办法是应用 subset() 函数。

subset(Familydata, sex == "F")
# 若只抉择女性中的变量 ht 和 wt
subset(Familydata, sex == "F", select = c(ht, wt))

留神,该命令只是抉择一个子集来显示,不会对原来的数据框产生任何影响。如果还要进一步应用该子集,须要把它存为一个新的对象。

在机器学习畛域,常常须要从数据集里随机抽取一部分样本。例如,咱们想把一个大的数据集随机分成两份,其中一份用于构建预测模型,另一份用于验证模型的预测精度。函数 sample() 可用于随机抽样,上面的命令从数据框 Familydata 里随机抽取一个大小为 3 的样本:

sample.rows <- sample(1:nrow(Familydata), size = 3, replace = FALSE)
sample.rows
# 5 4 1

函数 sample() 中的第一个参数是一个由要从中抽样的元素组成的向量,在这里是从 1 到数据框中的总观测数;第二个参数 size 是要抽取的元素的数量;第三个参数 replace 用于设定是否放回抽样,默认为 FALSE(不放回抽样)。

函数 sample() 的返回值可用于抉择数据框中的行。因为随机种子数的不同,每次运行失去的后果很可能不一样。

3. 将数据框依照某个变量的值排序:order()

有时咱们想将数据框依照某个变量的值的大小进行排序显示,这能够借助函数 order() 实现。例如,将数据框 Familydata 以变量 age 的值从小到大显示,能够应用上面的命令:

# , 前示意条件 , 后示意显示的列
Familydata[order(Familydata$age), ] # 默认升序
# 降序写法
Familydata[order(Familydata$age, decreasing = TRUE), ]
# 等价于 age 取反后果
Familydata[order(-Familydata$age), ]

4. 查找和删除反复数据:duplicated()

原始数据集里常常会有反复的行。如果不是反复测量的数据,数据集的每一行应该是某一个对象的观测,而且数据集里通常有一个用于辨认个体的变量(比方 id)。

数据集 Familydata 中的变量 code 就是个体辨认号,上面查看该变量有无反复值:

duplicated(Familydata$code)
# FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# 函数 duplicated() 的返回值是逻辑值 TRUE 或 FALSE,这里全为 FASLE,表明变量 code 没有反复值。

如果数据框的行数较多,逐个查看这些逻辑值会很麻烦。此时,能够将函数 any() 作用于函数 duplicated() 的输入后果:

any(duplicated(Familydata$code))
# FALSE

或者应用函数 table(),还能失去反复值的个数:

table(duplicated(Familydata$code))
# FALSE 
# 11

删除反复行

为了说明怎么删除反复的行,上面建设一个数据框 Familydata1,将原数据框 Familydata 的第 2 行增加在其第 12 行:

Familydata1 <- Familydata
Familydata1[12,] <- Familydata[2,]
Familydata1

应用函数 which() 能够找出变量 code 的反复值所在的行:

which(duplicated(Familydata1$code))

而后,删除反复的行:

# 将不反复的新建对象即可
unique.code.data <- Familydata1[!duplicated(Familydata1$code), ]
unique.code.data

identical 查看对象是否齐全一样

# 用 identical 查看两个对象是否齐全一样
identical(unique.code.data, Familydata)
# TRUE

5. 在数据框中增加和删除变量

在解决数据框时,咱们常常须要创立新的变量并把它增加到现有的数据框中。例如,建设一个新的变量 log10money,其值等于变量 money 以 10 为底的对数。最间接地,能够输出:

Familydata$log10money <- log10(Familydata$money)
# 或者能够应用 `transform( )` 函数:Familydata <- transform(Familydata, log10money = log10(money))
names(Familydata)
# 'code''age''ht''wt''money''sex''log10money'

与增加变量相同,如果想从数据框中删除一个变量,只需在方括号内 下标号的后面增加一个减号。例如:

Familydata[, -7]

请留神,该命令只显示所需的子集,对数据框自身不会产生影响。

然而赋一个空值(NULL)给数据框中的变量等同于删除该变量,并且是会永恒删除数据框中的变量:

Familydata$log10money <- NULL
colnames(Familydata)

6. 把数据框增加到搜寻门路

在后面查看和应用数据框中的变量时,咱们须要在变量名后面加上数据框名和符号 $。这种形式有时候会显得比拟繁缛,尤其是数据框和变量的名字都很长的时候。此时,函数 attach() 或者函数 with() 能够用来简化代码。

函数 attach() 能够 将数据框增加到搜寻门路中。输出以下命令:

attach(Familydata)

而后用函数 search() 查看搜寻门路中的所有对象:

search()
#'.GlobalEnv''Familydata''package:epiDisplay''package:nnet''package:MASS''package:survival''package:foreign''package:repr''jupyter:irkernel''package:stats''package:graphics''package:grDevices''package:utils''package:datasets''package:methods''Autoloads''package:base'

当初搜寻门路中的第二个地位寄存了数据框 Familydata。因为 数据框曾经在搜寻门路中了,而变量 age 又在该数据框里,所以当初能够间接应用变量 age 了。

summary(age)
#    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#    6.00   30.00   47.00   45.73   63.50   80.00 

把一个数据框放入搜寻门路相似于应用函数 library() 加载一个包。调入搜寻门路的数据框和加载的包都会被主动读入 R,并始终寄存在内存中直至它们被移出(detach())。

应用函数 attach() 尽管会在输出代码时带来一些便当,但同时也会带来一些问题。例如,反复加载数据框可能会最终导致系统资源适度负荷。另外,如果全局环境中或多个数据框中有雷同的变量名,容易使用户产生混同。因而,有些 R 的使用者 尽量避免应用函数 attach(),而应用函数 with()

datasets 包里的数据集 infert 为例:

with(infert, summary(age))
#  Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#  21.00   28.00   31.00   31.50   35.25   44.00 

函数 with() 的局限性在于,对于屡次应用数据框,咱们必须重复使用函数 with()。此外,赋值仅在此函数外部失效,例如:

with(infert, {m <- mean(age)}
  )
m 
# ERROR:object 'm' not found

抉择哪一种数据处理形式取决于剖析者的偏好。例如《R 语言医学数据分析实战》举荐的做法是:

  1. 在开启一个新的剖析我的项目时,首先应用命令 rm(list = ls()) 从 R 工作环境中革除所有对象;
  2. 在剖析过程中用函数 detach() 将不再须要应用的数据框从搜寻门路中移出;
  3. 不要定义与曾经存在于搜寻门路中的数据框同名的新对象;
正文完
 0