基本的程式筆記設定,安裝、載入一些基本的套件

rm(list=ls(all=T))
knitr::opts_chunk$set(comment = NA)
knitr::opts_knit$set(global.par = TRUE)
par(cex=0.8); options(scipen=20, digits=4, width=90)
if(!require(pacman)) install.packages("pacman")
pacman::p_load(magrittr)
這個區段主要是設定筆記網頁的格式和載入(安裝)一些基本的套件,請大家不要改動

【A】一個最簡單的R程式

Given a strategy which may lead to \(n\) different outcomes …

\[\pi = \sum_{i=1}^{n} p_i \times v_i \qquad(1)\]

1. 定義資料物件: 分別把報酬(\(v_i\))和機率(\(p_i\))放在vp這兩個數值向量之中

v = c(100, 50, -50, 0)
p = c(0.1, 0.2, 0.3, 0.4)

2. 執行運算式sum(p * v)這一個運算式算出\(\pi\)的值,放在pi這個物件裡面,

pi = sum(p * v)

3. 印出結果 並且把它列印出來

pi
[1] 5


【B】『值』的種類 Types of Automic Values

noTimes = 3L                   # 整數 integer
myWeight = 75.2                # 數值 numeric
isAsian = TRUE                 # 邏輯 Boolin
myName = "Tony Chuo"           # 字串 character 
date1 = as.Date("2019-01-01")  # 日期 Date


【C】基本資料結構 - 向量 Vector

(基本值的)向量物件

noBuy = c(3L, 5L, 1L, 1L, 3L)               # 整數向量
height = c(175, 168, 180, 181, 169)         # 數值向量
isMale = c(FALSE, TRUE, FALSE, TRUE, TRUE)  # 邏輯向量

字串向量

name = c("Amy", "Bob", "Cindy", "Danny", "Edward")  

類別向量

gender = factor( c("F", "M", "F", "M", "M") )     
skin_color = factor( c("black", "black", "white", "yellow", "white") )

💡 學習重點:
  ■ 向量是R的基本資料結構
  ■ 單值(如noTimemyWeightisAsianmyNamedate1)其實都是長度為1的向量物件
  ■ 在物件導向的語言裡面,資料結構又稱為Class
  ■ 我們可以用str()class()這兩個內建功能來查看物件的結構和種類

class(isMale)
[1] "logical"
class(gender)
[1] "factor"
str(gender)
 Factor w/ 2 levels "F","M": 1 2 1 2 2


【D】運算符號 (Operator)

  ■ 早期的R,其最主要的目的就是要簡化向量運算
  ■ 四則運算和內建功能大多都可以直接作用在向量上面

c(1, 2, 3, 4) * c(1, 10, 100, 1000)
[1]    1   20  300 4000

連續的整數

1:6
[1] 1 2 3 4 5 6

次方運算和科學記號

10^(-2:3)
[1]    0.01    0.10    1.00   10.00  100.00 1000.00

當向量不一樣長時 …

c(100, 200, 300, 400) / c(10, 20)
[1] 10 10 30 20

單值:長度為1的向量

c(100, 200, 300, 400) / 10
[1] 10 20 30 40
c(10,20,30,40,50,60,70,80) + c(1, 2, 3)
Warning in c(10, 20, 30, 40, 50, 60, 70, 80) + c(1, 2, 3): 較長的物件長度並非較短物件長度
的倍數
[1] 11 22 33 41 52 63 71 82

指定物件的名稱: =<- Assignment Operator

Prob = c(0.1, 0.2, 0.3, 0.4)
Value <- c(120, 100, -50, -60)
Prob * Value
[1]  12  20 -15 -24

邏輯運算 Logic Operator

c(0.1, 0.2, 0.3, 0.4) > c(0, 1, 2, 3)
[1]  TRUE FALSE FALSE FALSE
c(0.1, 0.2, 0.3, 0.4) < 0.25
[1]  TRUE  TRUE FALSE FALSE
c('Amy','Bob','Cindy','Danny') == 'Cindy'
[1] FALSE FALSE  TRUE FALSE
c(100, 200, 300, 400) %in% c(250, 300, 350, 400)
[1] FALSE FALSE  TRUE  TRUE

💡 學習重點:
  ■ 『指定(=, <-)』與『測試相等(==)』是兩個不同的運算符號
  ■ 邏輯運算的結果通常是一個邏輯向量



【E】功能(函數)與參數 Function & Argument

The Expected Payoff is: \(\sum p \times v\)

expPayoff = sum(Prob * Value)
expPayoff
[1] -7

內建功能通常第一個參數都是向量物件

sqrt(1:9)
[1] 1.000 1.414 1.732 2.000 2.236 2.449 2.646 2.828 3.000

💡 學習重點: R的功能通常都有很多個參數,我們需要注意參數的:
    ■ 名稱
    ■ 位置
    ■ 預設值

log(100, base=10)
[1] 2
help(log)
log(x=1000, base=10)
[1] 3
log(1000,10)
[1] 3

連續呼叫功能

round(sqrt(1:9), 2)
[1] 1.00 1.41 1.73 2.00 2.24 2.45 2.65 2.83 3.00

管線運算符號: %>%

sqrt(1:9) %>% round(2)
[1] 1.00 1.41 1.73 2.00 2.24 2.45 2.65 2.83 3.00


【F】向量索引 Vector Indexing

我們用索引來選擇資料結構中的子元件,索引本身也是向量,常用的索引方式包括:

位置索引:整數向量

noBuy[c(1, 5)]
[1] 3 3
height[2:4]
[1] 168 180 181
i = c(1:3, 5)
isMale[i]
[1] FALSE  TRUE FALSE  TRUE

名稱索引:字串向量 資料結構的子元件有名稱的時候

height
[1] 175 168 180 181 169
names(height) = c("Amy", "Bob", "Cindy", "Danny", "Edward")
height
   Amy    Bob  Cindy  Danny Edward 
   175    168    180    181    169 

我們可以用子元件的名稱來做索引

height[ c('Bob','Danny') ]
  Bob Danny 
  168   181 

條件索引:邏輯向量
條件索引基本上是和原向量一樣長的一個邏輯向量

noBuy[c(T,T,F,F,T)]
[1] 3 5 3
height[c(T,T,F,F,T)]
   Amy    Bob Edward 
   175    168    169 

💡: 條件索引讓我們可以使用邏輯運算式的結果當索引、使用條件來挑選資料結構子中的子元件

name[height > 170]
[1] "Amy"   "Cindy" "Danny"

🗿 練習:
請使用這些預先定義好的向量回答以下問題 …

noBuy = c(3L, 5L, 1L, 1L, 3L)                       # 整數向量
height = c(175, 168, 180, 181, 169)                 # 數值向量
isMale = c(FALSE, TRUE, FALSE, TRUE, TRUE)          # 邏輯向量
name = c("Amy", "Bob", "Cindy", "Danny", "Edward")  # 字串向量
gender = factor( c("F", "M", "F", "M", "M") )       # 邏輯向量
skin_color = factor( c("black", "black", "white", "yellow", "white") )  # 邏輯向量

🗿: 請列出 所有男生的名字

name[isMale]
[1] "Bob"    "Danny"  "Edward"

🗿: 請列出 身高大於180cm的人的名字

🗿: 請列出 身高大於180cm的黃種人的名字

🗿: 請算出 男生的平均身高

🗿: 請算出 女生總共買了多少次

🗿: 請算出 白種女生總共有多少人



【G】資料框 DataFrame

通常資料框中的每一筆記錄代表一個分析單位,每個欄位值代表分析單位之中的某一種屬性

df = data.frame(
  noBuy = c(3L, 5L, 1L, 1L, 3L),
  height = c(175, 168, 180, 181, 169),
  isMale = c(FALSE, TRUE, FALSE, TRUE, TRUE),
  name = c("Amy", "Bob", "Cindy", "Danny", "Edward"),
  gender = factor( c("F", "M", "F", "M", "M") ),
  skin_color = factor( c("black", "black", "white", "yellow", "white")),
  stringsAsFactors=FALSE
  )
df
  noBuy height isMale   name gender skin_color
1     3    175  FALSE    Amy      F      black
2     5    168   TRUE    Bob      M      black
3     1    180  FALSE  Cindy      F      white
4     1    181   TRUE  Danny      M     yellow
5     3    169   TRUE Edward      M      white

方便篩選

subset(df, isMale & skin_color == "black")
  noBuy height isMale name gender skin_color
2     5    168   TRUE  Bob      M      black

方便統計

mean(df$height)
[1] 174.6

分類運算

tapply(df$height, df$gender, mean)
    F     M 
177.5 172.7 


【H】資料框索引 DataFrame Indexing

資料框有非常多種索引方式,光是靠這一些索引方式,就可以做很精緻的探索性資料分析:

df[c(1,2), c(2,3)]
  height isMale
1    175  FALSE
2    168   TRUE
df[c(1,2), ]
  noBuy height isMale name gender skin_color
1     3    175  FALSE  Amy      F      black
2     5    168   TRUE  Bob      M      black
df[df$height < 175 & df$isMale, ]
  noBuy height isMale   name gender skin_color
2     5    168   TRUE    Bob      M      black
5     3    169   TRUE Edward      M      white
df[df$height < 175 & df$isMale, "name"]
[1] "Bob"    "Edward"
df$name[df$height < 175 & df$isMale]
[1] "Bob"    "Edward"
subset(df, height<175 & isMale)
  noBuy height isMale   name gender skin_color
2     5    168   TRUE    Bob      M      black
5     3    169   TRUE Edward      M      white
subset(df, height<175 & isMale, name)
    name
2    Bob
5 Edward
subset(df, height<175 & isMale)$name
[1] "Bob"    "Edward"
subset(df, height<175 & isMale, c(name, noBuy))
    name noBuy
2    Bob     5
5 Edward     3

🗿 練習:
以下的運算式分別代表什麼意思 …

df$name[df$isMale] # 所有男生的名字  
[1] "Bob"    "Danny"  "Edward"
df[df$height > 180 , "name"] # 
[1] "Danny"
subset(df, height > 170 & !isMale)$name # 
[1] "Amy"   "Cindy"
mean(df$height[df$isMale]) # 
[1] 172.7
df$height[!df$isMale] %>% mean # 
[1] 177.5
sum( subset(df, !isMale)$noBuy ) # 
[1] 4
subset(df, skin_color == "white" & !isMale ) %>% nrow # 
[1] 1
sum(df$skin_color == "white" & !df$isMale ) # 
[1] 1


📝 UNIT2A 學習重點:
  ■ 程式:使用『運算式』定義或變更『資料物件』的過程
  ■ 資料物件(object)的屬性:
    § 名稱(name)
    § 值(value)
    § 種類(data type): int, num, chr, logi, Date, …
    § 結構(class): 向量(vector), 矩陣(matrix), 資料框(data_frame), 序列(list), …
    § 大小(dim)
  ■ 運算式(expression)的組成:
    § 物件(object)
    § 運算符號(operator): {+, -, *, /}, {>, >=, ==}, {&, |}, …
    § 功能函數(function): 名稱, 參數, 參數次序, 預設值 …
  ■ 索引(Index):
    § 位置索引
    § 邏輯索引與條件選擇
    § 名稱索引
  ■ 資料框(data.frame):
    § 每一筆紀錄都有固定的欄位
    § 每一個欄位都有固定的格式
    § 每一筆紀錄和欄位都可以有名稱