3.6 检查变量
当在控制台输入一个运算或者变量时,结果就被打印出来,因为R隐式调用了对象的print
方法。
注意
对以下术语稍作解释:大多情况下,“方法”(method)和“函数”(function)是可以互换的。有时,R中的函数也称为面向对象中的方法。不同类型的对象有不同版本的
所以,在命令提示符下输入1 + 1
与print( 1 + 1)
一样。
但是,对于内循环或函数来说4,自动打印功能不起作用,我们必须显式地调用print
:
4 除非函数返回了值。
ulams_spiral <- c(1, 8, 23, 46, 77) # 参考http://oeis.org/A033951
for(i in ulams_spiral) i # 啊哦, 值没有打印出来
for(i in ulams_spiral) print(i)
## [1] 1
## [1] 8
## [1] 23
## [1] 46
## [1] 77
如果你是在终端而不是在GUI或IDE上运行R,在某些系统上这个问题的确存在。在这种情况下,你就一直需要显式调用print
函数。
大部分print
函数的实现建立在调用底层的cat
函数上。虽然你可能永远无需直接调用cat
(与之对应的用户级命令是print
和message
),但是仍应对此有所了解,以便在需要时亲自编写print
函数5
5 也许就像在练习16-3中那样。
注意
c
和cat
函数都是concatenate的缩写,但它们的作用完全不同!cat
是以Unix中的函数命名的。
除了查看变量的打印输出,最好也能看到某种程度的对象汇总信息。summary
函数就能为不同的数据类型提供汇总信息。例如,数值变量会被汇总统计出平均数、中位数,以及一些分位数(quantile)。在下例中,runif
函将数生成30个均匀分布于0和1之间的随机数:
num <- runif(30)
summary(num)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
##0.0211 0.2960 0.5060 0.5290 0.7810 0.9920
类别变量和逻辑向量将根据每个值的计算进行汇总。在下例中,letters
是一个内置的常数,它包含了从a到z的小写值(大写的LETTERS
则包括了类似的从A到Z的大写值)。这里letters[ 1:5]
用索引限制letters
的范围为从a到e。sample
函数使用重复抽样replace
随机抽样30
次:
fac <- factor(sample(letters[1:5], 30, replace = TRUE))
summary(fac)
## a b c d e
## 6 7 5 9 3
bool <- sample(c(TRUE, FALSE, NA), 30, replace = TRUE)
summary(bool)
## Mode FALSE TRUE NA's
## logical 12 11 7
多维对象与矩阵及数据框一样,都是通过列来汇总的(第4章和第5章将做更详细的讨论)。我们在下面创建的数据框dfr
非常大,显示出来足足有30行。对于这样的庞然大物 6,用head
函数即可仅显示它的前几行(默认为6行):
6 现在,30行的数据算不上是“大数据”,但在打印时它仍能占满整个屏幕。
dfr <- data.frame(num, fac, bool)
head(dfr)
## num fac bool
## 1 0.47316 b NA
## 2 0.56782 d FALSE
## 3 0.46205 d FALSE
## 4 0.02114 b TRUE
## 5 0.27963 a TRUE
## 6 0.46690 a TRUE
数据框的summary
函数就像为每列单独调用summary
一样:
summary(dfr)
## num fac bool
## Min. :0.0211 a:6 Mode :logical
## 1st Qu.:0.2958 b:7 FALSE:12
## Median :0.5061 c:5 TRUE :11
## Mean :0.5285 d:9 NA's :7
## 3rd Qu.:0.7808 e:3
## Max. :0.9916
类似地,str
函数能显示对象的结构。对向量来说,它并非很有趣(因为它们太简单了),但str
对数据框和嵌套列表非常有用:
str(num)
## num [1:30] 0.4732 0.5678 0.462 0.0211 0.2796 ...
str(dfr)
## 'data.frame': 30 obs. of 3 variables:
## $ num : num 0.4732 0.5678 0.462 0.0211 0.2796 ...
## $ fac : Factor w/ 5 levels "a","b","c","d",..: 2 4 4 2 1 1 4 2 1 4 ...
## $ bool: logi NA FALSE FALSE TRUE TRUE TRUE ...
如前所述,每个类都有自己的打印(print
)方法,以此控制如何显示到控制台。有时,这种打印模糊了其内部结构,或忽略了一些有用的信息。用unclass
函数可绕开这一点,显示变量是如何构建的。例如,对因子调用unclass
函数会显示它仅是一个整数(integer
)向量,拥有一个叫levels
的属性:
unclass(fac)
## [1] 2 4 4 2 1 1 4 2 1 4 3 3 1 5 4 5 1 5 1 2 2 3 4 2 4 3 4 2 3 4
## attr(,"levels")
## [1] "a" "b" "c" "d" "e"
稍后我们会讨论属性,而现在须了解的是,attributes
函数能显示当前对像的所有属性列表:
attributes(fac)
## $levels
## [1] "a" "b" "c" "d" "e"
##
## $class
## [1] "factor"
为了可视化诸如矩阵和数据框之类的二维变量,View
(请注意大写字母“V”)函数会把变量(只读的)显示为电子表格(spreadsheet)。edit
和fix
函数的工作方式与View
类似,但它允许手动更改数据值。虽然这听似更实用,但以这种方式编辑数据却是个无比糟糕的主意,因为我们会失去所有的可追溯性而无法追踪数据的出处。最好的方式还是使用编程来编辑数据:
View(dfr) #不允许更改
new_dfr <- edit(dfr) #更改将保存于new_dfr
fix(dfr) #更改将保存于dfr
一个好方法是结合View
和head
函数来查看数据框的前几行:
View(head(dfr, 50)) #查看前 50行