R 菜鸟入门篇 第02篇 数据

在第 01 篇里,我们学会了用 R 进行一般的数学运算和统计计算,并且做出了两张图:拜罗伊特降水的季节变化图,北京的 PM2.5 日变化图。很好,只是,这些数据总不能一个一个敲到代码里吧。要是处理保存在其他文件里的大量数据呢?本篇就解决这个问题。

开胃小菜: 在 Rstudio 左下窗口输入代码 demo(graphics),然后按回车,再回车,再回车,再回车……

点击这里下载一个数据文件,保存到一个文件夹里,比如 c:\R\data 文件夹(为避免不必要的麻烦,文件夹名称中都不要带空格和中文字符),我们看看如何对其中的数据进行操作。

首先,我们要告诉 R 数据在哪里。不习惯命令行的用户,可以这样获取这个文件的路径:

mydata1 <- file.choose() # 在弹出的窗口中选择文件,其路径存储到mydata里。
mydata1

这个文件的文件名叫做 dapengde_DummyR_PM25.csv 。鼠标选择文件比较麻烦,为了下次再使用这个代码的时候不必再点一次,一般都是直接输入文件路径:

mydata2 <- "c:\\R\\data\\dapengde_DummyR_PM25.csv"  # 路径要用引号(单双都行),表示这是一个字符串。
mydata2
## [1] "c:\\R\\data\\dapengde_DummyR_PM25.csv"

注意,文件路径中的斜线\本来是一个,但是在 R 代码中必须改成两个( 切记切记! ),或改成一个反斜线/,其中自有道理,暂时不必深究。

我们先在文件浏览器中双击打开这个文件看看,这是个 csv 文件,用记事本或 Excel 就可以打开,或者在 Rstudio 代码窗口输入

file.show(mydata2) # 查看文件

就会用默认程序打开。

这是2003 年 8 月在北京城区的三个高度(8 米,100 米,325 米)测得的 PM2.5 的质量浓度日变化(数据来源:Chan et al., 2005. Atmospheric Environment 39, no. 28 : 5113-5124),共 4 列 25 行。

现在让 R 读取文件。如果你喜欢拷贝粘贴的方式,那么可以在 Excel 选中数据区,拷贝,然后在 R 中这样读取其中的数据:

pm1 <- read.table(file = "clipboard", header = TRUE) # 读取剪切板里的数据,保存到 pm1 这个数据框变量里。header 表示数据的第一行为列名称。

Rstudio 右上窗就出现了 pm1 的信息,可以单击看内容,也可以用输入代码查看:

pm1

‘read.table’ 用来读取数据表格。看起来也太复杂了吧?怎么记得住?对,一般人都记不住,忘了就随手查查帮助,输入并运行:

?read.table

Rstudio此时会在右下窗显示帮助信息,有详细的解释和实例。好好读读吧,以后你会发现, 问号+函数名 是会经常用的命令。

R 菜鸟入门三大法宝:

  • 第一法宝: 问号 !问号+函数名,简直就是身边的诸葛亮,随时方便地查看帮助文档。
  • 第二法宝: googlewiki !大事不决问维基 ,小事不决问谷歌。
  • 第三法宝: 论坛 !内事不决问张昭(中文论坛,如这里),外事不决问周瑜(英文论坛,如这里)。

用拷贝粘贴的方式读取数据,优点是灵活,适合临时用一下。更多情况下,是直接按指定的路径去读文件:

pm2 <- read.table(file = mydata2, header = TRUE, sep = ",")  # 读取逗号分隔的数据。sep 表示数据列的分隔符。
pm <- read.csv(file = mydata2)  # 与上一个命令等同,专门用来读逗号分隔的文件。

你要问 ‘read.csv’是怎么回事?请试试你的第一法宝。

数据画个图看起来更直观:

plot(pm)

plot of chunk unnamed-chunk-3

任意两列的散点图就这么容易地做出来了。如果你有十列八列的,就会发现这是多么省事啊!懒人的福音啊!dapeng 一般在读入数据文件后的第一件事就是plot一下,对数据有个整体的感觉。第二件事一般是看看这个文件的总结报告

summary(pm)
##       time             h8             h100            h325      
##  Min.   : 0.00   Min.   : 46.0   Min.   : 32.0   Min.   : 30.0  
##  1st Qu.: 5.75   1st Qu.: 75.5   1st Qu.: 48.0   1st Qu.: 42.8  
##  Median :11.50   Median : 93.5   Median : 67.5   Median : 54.5  
##  Mean   :11.50   Mean   : 98.7   Mean   : 72.1   Mean   : 65.5  
##  3rd Qu.:17.25   3rd Qu.:128.0   3rd Qu.:100.0   3rd Qu.: 88.5  
##  Max.   :23.00   Max.   :150.0   Max.   :123.0   Max.   :126.0

这下可省事儿了,上一节我们用的最大值、最小值、中位数、平均值函数,用summary这一条命令就全部搞定,顺便还附送了四分位数(1st Qu., 3rd Qu.)。啥是四分位数?试试你的第二法宝。

怎么选取 pm 中的指定数值呢,比如说,9 点钟 8 米高处的PM2.5浓度?还记得上一节我们是如何选取 4 月的降水量吗?对,x[4]。类似地:

pm[10, 2]  # 第 10 行, 第 2 列。
## [1] 150

要选取多个行呢?若记得用c()生成一个向量,那就好办了,比如选取偶数行,即 0、2、4、…、22 点钟8 米处的 PM2.5 浓度:

pm[c(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22), 2]
##  [1]  80  91 100 144 150 106  68  46  68  92 108

这个 0 到 22 敲起来太麻烦了吧,懒人的办法是用seq()函数生成个数列:

pm[seq(0, 22, 2), 2]
##  [1]  80  91 100 144 150 106  68  46  68  92 108

seq(0, 22, 2) 表示以 0 为起点,22 为终点,间隔(即步长)为 2 生成一个数列。比如步长是 1 的话,就用seq(2, 22, 1)。当然,更懒的做法是:

pm[2:22, 2]
##  [1]  80  64  91  87 100 128 144 150 150 150 106  78  68  62  46  55  68
## [18]  84  92  95 108

这和上一条指令等效。

选取整行或整列:

pm[, 2]  # 第 2 列全部。
##  [1]  97  80  64  91  87 100 128 144 150 150 150 106  78  68  62  46  55
## [18]  68  84  92  95 108 128 138
pm[3, ]  # 第 3 行全部。
##   time h8 h100 h325
## 3    2 64   43   50

如果列数太多,总不能老去数第几列吧?别急,也可以这样选取:

pm[, "h8"]
##  [1]  97  80  64  91  87 100 128 144 150 150 150 106  78  68  62  46  55
## [18]  68  84  92  95 108 128 138

或者用美元符号

pm$h8
##  [1]  97  80  64  91  87 100 128 144 150 150 150 106  78  68  62  46  55
## [18]  68  84  92  95 108 128 138

h8 是要选取的列的名称。列名称都有哪些呢?用names()函数:

names(pm)
## [1] "time" "h8"   "h100" "h325"


练习02.1:请做出 100 米高处的 PM2.5 浓度日变化的散点图。
练习02.2:请计算 100 米高处 PM2.5 浓度的平均值,最大值,最小值,中值。

从此以后,只要把你的数据文件保存成.csv文件,R 就可以容易地读取,进行后续处理了!

有用的信息:

数据文件存储路径 不要空格,不要中文,读取时用双斜线。
读取文件 read.table(), read.csv()
选取单元格 pm[3, 2],pm[ , 2],pm[3, ],pm[,"h8"],pm$h8

连载中,待续

R 菜鸟入门篇 第02篇 数据》上有30条评论

  1. 青依

    dapeng,我有个表,里面大概有几万行,用read.table读取此文件,显示的结果都是只有一千多行,然后最后有一行提示我还有多少rows没有读入,这个怎么办呢?因为我要对这个表进行下一步的操作,不完全读入,没办法操作啊

    回复
    1. 双鱼菜鸟

      你把那个文件放在Rstudio的bin目录里,就可以了,我也碰到过这个问题,还有你的文件名字里还不能有汉字,否则也读取不了,这是我碰到的,然后是这么解决的

      回复
  2. wwq

    > pm[0,0]数据框没有列但有0行> pm[0,1]integer(0)> pm[0,2]integer(0)> pm[1,2] 97

    回复
    1. 大鹏 文章作者

      抱歉,被我不慎删掉了。已恢复,可以下载了。

      回复
  3. kreaty

    pm[9, 2] # 第 9 行, 第 2 列。这个应该输出的是8点8米的值吧,虽然和9点一样,但是从0开始算的话,9点应该是在第十行

    回复
    1. 大鹏 文章作者

      您说得对,已经有网友指出错误了,见5楼。谢谢。这就改。

      回复
      1. kreaty

        pm[8, 2] # 第 9 行, 第 2 列。应该改成pm[10,2],麻烦再改下吧,容易误导。
        因为我太菜鸟了,和你一样是没有太多统计基础的工科生,所以很需要您这一系列的入门手册。

        回复
        1. 大鹏 文章作者

          啊哦,我怎么糊涂了。谢谢斧正。

  4. Lisa

    我有个地方不会,就是我的文件格式已经是.RData格式了,可是我在Rstudio中怎么调用这个文件啊。。。

    回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax