R語言程式設計導論

林嶔 (Lin, Chin)

Lesson 3 檔案讀取/寫出與基本操作

第一節:陣列(Array)層物件基本介紹(1)

– 陣列(Array)層分為矩陣(matrix)及資料表(data.frame):

  1. 矩陣(matrix)要求裡面的每個元素都為單一種類,因此與變數(Variable)層的向量類似,分為邏輯(logical)矩陣、整數(integer)矩陣、數字(numeric)矩陣、文字(character)矩陣[注意:因子(factor)向量被轉為矩陣時會變為文字矩陣]

  2. 資料表(data.frame)可以允許每欄有不同的屬性,一個資料表內可以同時擁有不同屬性的變項。

# 數値矩陣物件(注意將數字填入矩陣時的順序)
x1 = 1:20
M1 = matrix(x1, nrow = 4, ncol = 5)
M1
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    5    9   13   17
## [2,]    2    6   10   14   18
## [3,]    3    7   11   15   19
## [4,]    4    8   12   16   20
# 因子矩陣物件
x2 = c(0, 1, 2, 0, 2, 1, 1, 2, 0)
x2 = as.factor(x2)

M2 = matrix(x2, nrow = 3, ncol = 3)
M2

第一節:陣列(Array)層物件基本介紹(2)

  1. 函數「t()」可以求得轉置矩陣

  2. 函數「solve()」可以求得反矩陣

  3. 矩陣的乘法需要利用函數「%*%」來完成

x = 1:4
X = matrix(x, nrow = 2, ncol = 2)

X
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
t(X)
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
solve(X)
##      [,1] [,2]
## [1,]   -2  1.5
## [2,]    1 -0.5
y = 2:5
Y = matrix(y, nrow = 2, ncol = 2)
Y
##      [,1] [,2]
## [1,]    2    4
## [2,]    3    5
#注意下列兩者的差異
X%*%Y
##      [,1] [,2]
## [1,]   11   19
## [2,]   16   28
X*Y
##      [,1] [,2]
## [1,]    2   12
## [2,]    6   20

第一節:陣列(Array)層物件基本介紹(3)

  1. 函數「length()」可以仍然可以用來查詢此陣列的總長度(長*寬)

  2. 函數「nrow()」、「ncol()」可以查詢陣列的列欄數目

x1 = 1:20
M1 = matrix(x1, nrow = 4, ncol = 5)

length(M1)
## [1] 20
nrow(M1)
## [1] 4
ncol(M1)
## [1] 5

第一節:陣列(Array)層物件基本介紹(4)

x1 = 1:20
M1 = matrix(x1, nrow = 4, ncol = 5)
M1
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    5    9   13   17
## [2,]    2    6   10   14   18
## [3,]    3    7   11   15   19
## [4,]    4    8   12   16   20
# 猜猜這些指令是叫出哪個數字
M1[3,4]
M1[2,5]
M1[4,1]
# 也猜猜這些指令是叫出哪個東西
M1[3,]
M1[,1]
M1[,c(2, 5)]

第一節:陣列(Array)層物件基本介紹(5)

x1 = 1:20
M1 = matrix(x1, nrow = 4, ncol = 5)
rownames(M1) = c("a", "b", "c", "d")
M1
##   [,1] [,2] [,3] [,4] [,5]
## a    1    5    9   13   17
## b    2    6   10   14   18
## c    3    7   11   15   19
## d    4    8   12   16   20
colnames(M1) = c("A", "B", "C", "D", "E")
M1
##   A B  C  D  E
## a 1 5  9 13 17
## b 2 6 10 14 18
## c 3 7 11 15 19
## d 4 8 12 16 20
M1["c","A"]
M1[,c("E", "C")]
colnames(M1)[3] = "ZZZ"
M1
##   A B ZZZ  D  E
## a 1 5   9 13 17
## b 2 6  10 14 18
## c 3 7  11 15 19
## d 4 8  12 16 20

第一節:陣列(Array)層物件基本介紹(6)

x1 = 1:20
M1 = matrix(x1, nrow = 4, ncol = 5)
D1 = data.frame(M1)
D1
##   X1 X2 X3 X4 X5
## 1  1  5  9 13 17
## 2  2  6 10 14 18
## 3  3  7 11 15 19
## 4  4  8 12 16 20
rownames(M1) = c("a", "b", "c", "d")
colnames(M1) = c("A", "B", "C", "D", "E")

D2 = data.frame(M1)
D2
##   A B  C  D  E
## a 1 5  9 13 17
## b 2 6 10 14 18
## c 3 7 11 15 19
## d 4 8 12 16 20
colnames(D1) = c("A", "B", "C", "D", "E")
D1
##   A B  C  D  E
## 1 1 5  9 13 17
## 2 2 6 10 14 18
## 3 3 7 11 15 19
## 4 4 8 12 16 20

第一節:陣列(Array)層物件基本介紹(7)

a = c(TRUE, FALSE, TRUE, FALSE, FALSE)
class(a)
## [1] "logical"
b = c(0.7, -0.9, 1.2, -2.1, 3.7)
class(b)
## [1] "numeric"
c = c("A", "B", "C", "C", "B")
c = as.factor(c)
class(c)
## [1] "factor"
DATA = data.frame(a, b, c)
DATA
##       a    b c
## 1  TRUE  0.7 A
## 2 FALSE -0.9 B
## 3  TRUE  1.2 C
## 4 FALSE -2.1 C
## 5 FALSE  3.7 B
class(DATA[,1])
## [1] "logical"
class(DATA[,2])
## [1] "numeric"
class(DATA[,3])
## [1] "factor"

第一節:陣列(Array)層物件基本介紹(8)

DATA$b
## [1]  0.7 -0.9  1.2 -2.1  3.7
DATA[,2]
## [1]  0.7 -0.9  1.2 -2.1  3.7
DATA[,"b"]
## [1]  0.7 -0.9  1.2 -2.1  3.7
a = c(TRUE, FALSE, TRUE, FALSE, FALSE)
b = c(0.7, -0.9, 1.2, -2.1, 3.7)
c = c("A", "B", "C", "C", "B")
DATA = data.frame(a, b, c)
DATA
##       a    b c
## 1  TRUE  0.7 A
## 2 FALSE -0.9 B
## 3  TRUE  1.2 C
## 4 FALSE -2.1 C
## 5 FALSE  3.7 B
DATA$d = c(1, 5, 8, 9, 12)
DATA
##       a    b c  d
## 1  TRUE  0.7 A  1
## 2 FALSE -0.9 B  5
## 3  TRUE  1.2 C  8
## 4 FALSE -2.1 C  9
## 5 FALSE  3.7 B 12
x = 1:4
X = matrix(x, nrow = 2, ncol = 2)
y = 2:5
Y = matrix(y, nrow = 2, ncol = 2)

rbind(X, Y)
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
## [3,]    2    4
## [4,]    3    5
rbind(Y, X)
##      [,1] [,2]
## [1,]    2    4
## [2,]    3    5
## [3,]    1    3
## [4,]    2    4
cbind(X, Y)
##      [,1] [,2] [,3] [,4]
## [1,]    1    3    2    4
## [2,]    2    4    3    5
x = 1:4
y = 6:8

# 問題,如何合併它們並儲存成物件z呢?

練習1:九九乘法表

– 另外,你是否能『不依靠』雙層迴圈產生九九乘法表呢?

##       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
##  [1,]    1    2    3    4    5    6    7    8    9
##  [2,]    2    4    6    8   10   12   14   16   18
##  [3,]    3    6    9   12   15   18   21   24   27
##  [4,]    4    8   12   16   20   24   28   32   36
##  [5,]    5   10   15   20   25   30   35   40   45
##  [6,]    6   12   18   24   30   36   42   48   54
##  [7,]    7   14   21   28   35   42   49   56   63
##  [8,]    8   16   24   32   40   48   56   64   72
##  [9,]    9   18   27   36   45   54   63   72   81

練習1答案

x = matrix(0, nrow = 9, ncol = 9) # 先產生一個空矩陣

for (i in 1:9) {
  for (j in 1:9) {
    x[i,j] = i * j
  }
}

x
##       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
##  [1,]    1    2    3    4    5    6    7    8    9
##  [2,]    2    4    6    8   10   12   14   16   18
##  [3,]    3    6    9   12   15   18   21   24   27
##  [4,]    4    8   12   16   20   24   28   32   36
##  [5,]    5   10   15   20   25   30   35   40   45
##  [6,]    6   12   18   24   30   36   42   48   54
##  [7,]    7   14   21   28   35   42   49   56   63
##  [8,]    8   16   24   32   40   48   56   64   72
##  [9,]    9   18   27   36   45   54   63   72   81
x = 1:9
x %*% t(x)
##       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
##  [1,]    1    2    3    4    5    6    7    8    9
##  [2,]    2    4    6    8   10   12   14   16   18
##  [3,]    3    6    9   12   15   18   21   24   27
##  [4,]    4    8   12   16   20   24   28   32   36
##  [5,]    5   10   15   20   25   30   35   40   45
##  [6,]    6   12   18   24   30   36   42   48   54
##  [7,]    7   14   21   28   35   42   49   56   63
##  [8,]    8   16   24   32   40   48   56   64   72
##  [9,]    9   18   27   36   45   54   63   72   81

第二節:讀取資料表(1)

– 這個檔案是105年4月25日早上5點30台北市各監測站各空氣汙染物濃度的檔案。

– 使用函數「read.csv()」讀取csv檔

dat = read.csv("monitoring_1.csv", header = TRUE, fileEncoding = 'CP950') #請將路徑改為自己放置的位置
help(read.csv)
?read.csv #也可以這樣查詢
class(dat)
## [1] "data.frame"

第二節:讀取資料表(2)

  1. 函數「head()」可以查看資料表的前6列
  2. 函數「summary()」可以查看此資料表大致的資料結構
head(dat)
##                  time    device_id s_d0  s_t0 s_h0      lat      lon   school
## 1 2016-04-25 04:42:16 28C2DDDD4505   17 29.75   77 24.99643 121.5483 景興國小
## 2 2016-04-25 05:25:11 28C2DDDD450C   27 27.50   87 25.05221 121.5637 西松國小
## 3 2016-04-25 05:23:57 28C2DDDD4534   27 30.00   65 25.08374 121.5070 葫蘆國小
## 4 2016-04-25 05:25:13 28C2DDDD47C6   30 26.12   93 25.01992 121.5305 溫州國宅
## 5 2016-04-25 05:24:48 28C2DDDD4234   30 28.00   83 25.00244 121.5519 興隆國小
## 6 2016-04-25 05:24:48 28C2DDDD4234   30 28.00   83 25.00244 121.5519 興隆國小
##            time2
## 1 2016/4/25 5:30
## 2 2016/4/25 5:30
## 3 2016/4/25 5:30
## 4 2016/4/25 5:30
## 5 2016/4/25 5:30
## 6 2016/4/25 5:30
summary(dat)
##                   time           device_id       s_d0            s_t0      
##  2016-04-25 05:23:46: 2   28C2DDDD41FA: 2   Min.   :17.00   Min.   :26.12  
##  2016-04-25 05:24:00: 2   28C2DDDD4234: 2   1st Qu.:31.50   1st Qu.:27.75  
##  2016-04-25 05:24:48: 2   28C2DDDD400A: 1   Median :35.50   Median :28.00  
##  2016-04-25 04:42:16: 1   28C2DDDD41B2: 1   Mean   :34.86   Mean   :28.10  
##  2016-04-25 05:23:45: 1   28C2DDDD41C0: 1   3rd Qu.:38.25   3rd Qu.:28.53  
##  2016-04-25 05:23:54: 1   28C2DDDD41EB: 1   Max.   :43.00   Max.   :30.00  
##  (Other)            :19   (Other)     :20                                  
##       s_h0             lat             lon             school  
##  Min.   : 65.00   Min.   :24.99   Min.   :121.5   民生國小: 2  
##  1st Qu.: 84.00   1st Qu.:25.03   1st Qu.:121.5   興隆國小: 2  
##  Median : 88.00   Median :25.05   Median :121.5   仁愛國小: 1  
##  Mean   : 89.39   Mean   :25.05   Mean   :121.5   內湖國小: 1  
##  3rd Qu.: 89.75   3rd Qu.:25.07   3rd Qu.:121.6   南湖國小: 1  
##  Max.   :151.00   Max.   :25.13   Max.   :121.6   古亭國小: 1  
##                                                   (Other) :20  
##             time2   
##  2016/4/25 5:30:28  
##                     
##                     
##                     
##                     
##                     
## 

練習2:使用迴圈功能檢查資料

  1. 請檢查school這個欄位是否重複
  2. 請多創造一個欄位,並標記這列是否重複(欄位名稱隨便)
  3. 請執行一個迴圈,從此欄位的第一個值開始檢查,每次迴圈開始時就檢查資料表上面的國小中是否存在與現在位置名稱完全相等的國小

註:我們在確認時可能會用到一個新函數「%in%」,它的功能是確認左邊的物件是否有在右邊的物件中出現過,如下

dat[5,"school"] 
## [1] 興隆國小
## 26 Levels: 仁愛國小 內湖國小 南湖國小 古亭國小 ... 西門國小
dat[1:4,"school"]
## [1] 景興國小 西松國小 葫蘆國小 溫州國宅
## 26 Levels: 仁愛國小 內湖國小 南湖國小 古亭國小 ... 西門國小
dat[5,"school"] %in% dat[1:4,"school"]
## [1] FALSE
dat[6,"school"] 
## [1] 興隆國小
## 26 Levels: 仁愛國小 內湖國小 南湖國小 古亭國小 ... 西門國小
dat[1:5,"school"]
## [1] 景興國小 西松國小 葫蘆國小 溫州國宅 興隆國小
## 26 Levels: 仁愛國小 內湖國小 南湖國小 古亭國小 ... 西門國小
dat[6,"school"] %in% dat[1:5,"school"]
## [1] TRUE

練習2答案

i = 2
dat[i,"school"]  %in% dat[1:(i-1),"school"]
i = 3
dat[i,"school"]  %in% dat[1:(i-1),"school"]
i = 4
dat[i,"school"]  %in% dat[1:(i-1),"school"]
i = 5
dat[i,"school"]  %in% dat[1:(i-1),"school"]
i = 6
dat[i,"school"]  %in% dat[1:(i-1),"school"]
dat$DUP = FALSE # 也可以用「dat[,'DUP'] = FALSE」新增

for (i in 2:nrow(dat)) {
  dat[i,'DUP'] = dat[i,"school"]  %in% dat[1:(i-1),"school"]
}

head(dat)
##                  time    device_id s_d0  s_t0 s_h0      lat      lon   school
## 1 2016-04-25 04:42:16 28C2DDDD4505   17 29.75   77 24.99643 121.5483 景興國小
## 2 2016-04-25 05:25:11 28C2DDDD450C   27 27.50   87 25.05221 121.5637 西松國小
## 3 2016-04-25 05:23:57 28C2DDDD4534   27 30.00   65 25.08374 121.5070 葫蘆國小
## 4 2016-04-25 05:25:13 28C2DDDD47C6   30 26.12   93 25.01992 121.5305 溫州國宅
## 5 2016-04-25 05:24:48 28C2DDDD4234   30 28.00   83 25.00244 121.5519 興隆國小
## 6 2016-04-25 05:24:48 28C2DDDD4234   30 28.00   83 25.00244 121.5519 興隆國小
##            time2   DUP
## 1 2016/4/25 5:30 FALSE
## 2 2016/4/25 5:30 FALSE
## 3 2016/4/25 5:30 FALSE
## 4 2016/4/25 5:30 FALSE
## 5 2016/4/25 5:30 FALSE
## 6 2016/4/25 5:30  TRUE

第三節:簡單資料清理及寫出檔案(1)

– 函數「duplicated()」可以直接找尋整個資料表是否有重複的列

dat$DUP1 = duplicated(dat)
dat[,c("school", "DUP1")]
##                      school  DUP1
## 1                  景興國小 FALSE
## 2                  西松國小 FALSE
## 3                  葫蘆國小 FALSE
## 4                  溫州國宅 FALSE
## 5                  興隆國小 FALSE
## 6                  興隆國小 FALSE
## 7                  萬大國小 FALSE
## 8                  舊莊國小 FALSE
## 9  台北市立大學附設實驗國小 FALSE
## 10                 古亭國小 FALSE
## 11                 永建國小 FALSE
## 12                 福林國小 FALSE
## 13                 清江國小 FALSE
## 14                 富安國小 FALSE
## 15                 敦化國小 FALSE
## 16                 潭美國小 FALSE
## 17                 西門國小 FALSE
## 18                 仁愛國小 FALSE
## 19                 文湖國小 FALSE
## 20                 大佳國小 FALSE
## 21                 吉林國小 FALSE
## 22                 懷生國小 FALSE
## 23                 大同國小 FALSE
## 24                 內湖國小 FALSE
## 25                 民生國小 FALSE
## 26                 立農國小 FALSE
## 27                 民生國小 FALSE
## 28                 南湖國小 FALSE
dat$DUP2 = duplicated(dat$school)
dat[,c("school", "DUP1", "DUP2")]
##                      school  DUP1  DUP2
## 1                  景興國小 FALSE FALSE
## 2                  西松國小 FALSE FALSE
## 3                  葫蘆國小 FALSE FALSE
## 4                  溫州國宅 FALSE FALSE
## 5                  興隆國小 FALSE FALSE
## 6                  興隆國小 FALSE  TRUE
## 7                  萬大國小 FALSE FALSE
## 8                  舊莊國小 FALSE FALSE
## 9  台北市立大學附設實驗國小 FALSE FALSE
## 10                 古亭國小 FALSE FALSE
## 11                 永建國小 FALSE FALSE
## 12                 福林國小 FALSE FALSE
## 13                 清江國小 FALSE FALSE
## 14                 富安國小 FALSE FALSE
## 15                 敦化國小 FALSE FALSE
## 16                 潭美國小 FALSE FALSE
## 17                 西門國小 FALSE FALSE
## 18                 仁愛國小 FALSE FALSE
## 19                 文湖國小 FALSE FALSE
## 20                 大佳國小 FALSE FALSE
## 21                 吉林國小 FALSE FALSE
## 22                 懷生國小 FALSE FALSE
## 23                 大同國小 FALSE FALSE
## 24                 內湖國小 FALSE FALSE
## 25                 民生國小 FALSE FALSE
## 26                 立農國小 FALSE FALSE
## 27                 民生國小 FALSE  TRUE
## 28                 南湖國小 FALSE FALSE
all.equal(dat$DUP1, dat$DUP2)
## [1] "2 element mismatches"

第三節:簡單資料清理及寫出檔案(2)

– 由於我們已經創造了一個新變數「DUP」,若他為FALSE就是唯一的個案,TRUE的就是重複的

dat.clean = dat[dat$DUP1==FALSE,]
write.csv(dat.clean, "monitoring_clean.csv", fileEncoding = 'CP950')

練習3:使用help查詢函數參數並修改寫出的檔案樣貌

  1. 第一個欄位是列名稱,但這其實不需要,所以請在寫出檔案時請R不要把列名稱寫出
  2. 寫出的時候有DUP1、DUP2兩個變數,希望刪除

練習3答案

write.csv(dat.clean, "monitoring_clean.csv", fileEncoding = 'CP950', row.names = FALSE)
write.csv(dat.clean[,1:9], "monitoring_clean.csv", fileEncoding = 'CP950', row.names = FALSE)

小結

– 本節課學到功能如下,同學務必熟悉本次課程的內容:

  1. 資料讀入及寫出
  2. 簡單的資料清理
  3. 利用help查詢函數參數