物件導向設計(object-oriented design, OOD或者object-oriented programming, OOP)。
以前的BASIC語言是一連串的函式,加上迴圈,例如:
10 LET SUM=0
20 FOR I = 1 TO 10
30 LET SUM = SUM + I
40 NEXT I
50 PRINT “Sum is”; SUM
60 END
BASIC後來轉變成物件導向,例如Virtual Basic。另外一個語言:Fortran一開始也是程序性而不是物件導向,後來引進Module的概念,才慢慢轉向物件導向。
物件導向設計中的物件是「類」(class)的實例,類包括數字、字串,物件則是例如1到10的數字,或者26個英文字母等等。
OOP允許一個物件可以繼承其他物件的特質,例如\(\texttt{setClass()}\)一個類稱為Shape,然後再設定Polygon,同時舉例「邊」為integer,這一類可以繼承Shape,依此類推。
setClass("Shape")
setClass("Polygon", representation(sides = "integer"), contains = "Shape")
setClass("Triangle", contains = "Polygon")
setClass("Square", contains = "Polygon")
setClass("Circle", contains = "Shape")
R
他是多邊形,而且有5個邊:pentagon <- new("Polygon", sides = 5L)
pentagon
## An object of class "Polygon"
## Slot "sides":
## [1] 5
R
是物件導向(object-oriented)的語言。物件導向的意思是可以包裹資料或者函數在一個物件。例如指定一個數字性質的向量物件:
# Create a vector
my_vector <- c(1, 2, 3, 4, 5)
# Check its class (shows the type of object)
class(my_vector)
## [1] "numeric"
R
這個物件的性質,例如:
# Add an attribute to the vector object
attr(my_vector, "description") <- "This is a numeric vector"
# Check the attributes of the object
attributes(my_vector)
## $description
## [1] "This is a numeric vector"
# Create a function and assign it to an object
greet <- function(name) {
paste("Hello,", name)
}
# Use the function object
greet("Alice")
## [1] "Hello, Alice"
greet("Mr. President")
## [1] "Hello, Mr. President"
R
可以指定一個物件或者值(value)給一個名稱(name),不同名稱可以指向同一個物件。例如:
a <- c(1, 3, 5); a
## [1] 1 3 5
b <- a; b
## [1] 1 3 5
b[[3]] <- 10; b
## [1] 1 3 10
R
的名稱不可以有特殊符號或者是數字在第一個字母,例如無法執行以下的語法:
&a <- c(2, 1)
_b <- c(0, 2, 1)
1c <- c(1000)
.c <- c(10); .c
## [1] 10
`_YB` <- c(1:10); `_YB`
## [1] 1 2 3 4 5 6 7 8 9 10
R
會把名稱指向新的值,舊的值被取代,例如:
U <- c(5, 6, 7); U
## [1] 5 6 7
U <- c(9, 10, 11); U
## [1] 9 10 11
coin <- c("heads", "tails")
R
有一個物件coins的特性是coin:# object coin via structure()
coins <- structure(c("heads", "tails"), class = "coin")
coins
## [1] "heads" "tails"
## attr(,"class")
## [1] "coin"
sample()
這個隨機抽樣的函數模擬擲硬幣:toss <- function(x, times = 1, p = prob) {
sample(x, size = times, replace = TRUE, prob = p)
}
# tossing a coin 5 times
toss(coins, times = 6, p = c(0.55,0.45))
## [1] "tails" "heads" "tails" "tails" "tails" "heads"
g(x) <- c(1)
g(x)
g <- c(2d)
g
R
寫函式(function),由語法構成一連串過程。例如我們想用f這個函式來表示a這一個向量:
f <- function(a) {
a
}
f
## function(a) {
## a
## }
x <- c(1, 2, 3)
x
## [1] 1 2 3
f(x)
## [1] 1 2 3
z <- f(x)
z
## [1] 1 2 3
z <- f(10-1) ; z
## [1] 9
h <- function(r){
pi * r^2
}
r <- c(1, 2, 3)
h(r)
l1 <- c(1, 2, 3) ; l1
## [1] 1 2 3
l1 <- c(1, 2, 3)
l2 <- l1; l2
## [1] 1 2 3
l2[[3]] <- 20; l2
## [1] 1 2 20
R
的講義有提到列表的特性之一是可以允許不同長度的變數,例如:A.l <- list(a=c(1,2,3), b = c('D', 'E', 'F', 'G'),
c = c(1L, 2L, 3L, 4L, 5L))
A.l
## $a
## [1] 1 2 3
##
## $b
## [1] "D" "E" "F" "G"
##
## $c
## [1] 1 2 3 4 5
# Function 1: Calculates the sum and product of two numbers
calculate_sum_product <- function(a, b) {
sum_result <- a + b
product_result <- a * b
return(list(a=a, b=b, sum = sum_result, product = product_result))
}
A <- calculate_sum_product(c(1, 2, 3), 2)
A
## $a
## [1] 1 2 3
##
## $b
## [1] 2
##
## $sum
## [1] 3 4 5
##
## $product
## [1] 2 4 6
x1 <- list(y = 1:10)
x2 <- x1
x1; x2
x2[[1]]
d1 <- data.frame(x = c(1, 5, 6), y = c(2, 6, 7))
d1
## x y
## 1 1 2
## 2 5 6
## 3 6 7
d2 <- d1; d2
## x y
## 1 1 2
## 2 5 6
## 3 6 7
d2[, 2] <- d2[, 2] * 2; d2
## x y
## 1 1 4
## 2 5 12
## 3 6 14
# Install if you haven't already: install.packages("tibble")
library(tibble)
df_tibble <- tibble(
Name = c("Alice", "Bob", "Charlie", "Mario"),
Age = c(25, 30, 28, 40),
City = c("New York", "London", "Paris", "Florence"),
Nation =c("US")
)
print(df_tibble)
## # A tibble: 4 × 4
## Name Age City Nation
## <chr> <dbl> <chr> <chr>
## 1 Alice 25 New York US
## 2 Bob 30 London US
## 3 Charlie 28 Paris US
## 4 Mario 40 Florence US
x <- c('a', 'a', 'abc', 'd')
class(x)
## [1] "character"
library(stringr)
x <- c(" a ", "b ", " c", "d e ff")
x
## [1] " a " "b " " c" "d e ff"
str_trim(x)
## [1] "a" "b" "c" "d e ff"
rlang::current_env()
## <environment: R_GlobalEnv>
e1 <- rlang::env(
a = FALSE,
b = "a",
c = 2.3,
d = 1:3,
e = 3L,
); rlang::env_names(e1)
## [1] "a" "b" "c" "d" "e"
e1$a
## [1] FALSE
a
## [1] 1 3 5
identical(e1$b, b)
## [1] FALSE
e1$d <- e1
rlang::env_names(e1)
## [1] "a" "b" "c" "d" "e"
e2 <- rlang::as_environment(e1)
rlang::env_names(e2)
## [1] "a" "b" "c" "d" "e"
base
這個套件中,有一個函式typeof
,它可以回傳我們想知道的物件的性質:x <- 8;
base::typeof(x)
## [1] "double"
base::typeof('a')
## [1] "character"
hello <- function() {
print('Hello, world!')
}
class(hello)
## [1] "function"
typeof(hello)
## [1] "closure"
R
顯示closure,意思為這個函數所用到的指令以及變數都已經在所處的環境之中。
藉由套件,我們可以使用各種現有的語法、資料。當R
不斷一直擴充,而且是免費使用,我們就不斷有新的工具。
R
有許多套件,不同套件裡面的函數可能有同樣的命名。R
的套件(package)有一個介面稱為套件環境,我們可以告訴R
要用哪一個套件裡面的功能,以免R
需要搜尋所有的套件。例如J <- c(1, 2, 3, 3, 4, 4, 5, 5, 5, 95, 97, 98)
J1 <- car::recode(J, "1:2=1; 3=2; 4:5=3; 95:98=NA"); J1
## [1] 1 1 2 2 3 3 3 3 3 NA NA NA
J2 <- dplyr::recode(J, `1`='1', `2`='1', `3`='2', `4`='3', `5`='3', .default = NA_character_); J2 <- as.numeric(J2); J2
## [1] 1 1 2 2 3 3 3 3 3 NA NA NA
函數的名稱一樣,但是寫法不一樣,如果沒有告訴R
要用哪一個套件底下的語法,R
會去使用已經載入的套件,但是這不一定是使用者想要的套件。
未來上課時我們會盡量寫namespace,以免混淆。
R
有許多統計的套件,從描述統計到多變量分析都有,還有抽樣、加權等等跟調查相關的套件。R
有機器學習的套件,可以給它資料、隨機分派之後估計模型,然後應用在沒有被訓練的資料,比較預測值以及觀察值的差距。R
可以結合善於儲存樹狀結構資料的JSON,下載網路上的資料:library(httr)
library(jsonlite)
options(stringsAsFactors = F)
url_sc_flu <- "https://od.cdc.gov.tw/eic/Weekly_Age_County_Gender_487a.json"
df <- fromJSON(content(GET(url_sc_flu), "text", encoding = "utf-8"))
head(df)
## 確定病名 發病年份 發病週別 縣市 鄉鎮 性別 是否為境外移入 年齡層
## 1 487a 2003 2 新北市 永和區 M 0 10~14
## 2 487a 2003 3 台北市 中正區 M 0 3
## 3 487a 2003 3 新北市 永和區 F 0 4
## 4 487a 2003 4 台北市 大同區 F 0 3
## 5 487a 2003 5 新北市 汐止區 M 0 0
## 6 487a 2003 5 新北市 汐止區 M 0 2
## 確定病例數 縣市別代碼 鄉鎮別代碼
## 1 1 65000 65000040
## 2 1 63000 63000050
## 3 1 65000 65000040
## 4 1 63000 63000060
## 5 1 65000 65000110
## 6 1 65000 65000110
#load package
library(rvest); library(tidyverse); library(rLTP)
#webpage
webp2020 <-"http://vote.nccu.edu.tw/cec/vote312.asp?pass1=I:8:8IAA8888888888"
#list
presd2020 <- list()
#read html in a list with correct encoding
presd2020 <-read_html(webp2020, encoding = "BIG5") %>%
html_nodes(xpath='//table') %>%
html_table()
#data frame
presd2020.dt <- presd2020[[1]]
#rename the column names as the first row and delete the first row
rownames(presd2020.dt) <-NULL
colnames(presd2020.dt) <- presd2020.dt[1, ]
presd2020.dt <- presd2020.dt[-1, ]
#Done!
head(presd2020.dt)
## # A tibble: 6 × 5
## 地區 姓名 號次 得票數 得票率
## <chr> <chr> <chr> <chr> <chr>
## 1 宜蘭縣 宋楚瑜 01 10739 3.9135%
## 2 宜蘭縣 韓國瑜 02 90010 32.8018%
## 3 宜蘭縣 蔡英文 03 173657 63.2847%
## 4 新竹縣 宋楚瑜 01 18435 5.6716%
## 5 新竹縣 韓國瑜 02 154224 47.4478%
## 6 新竹縣 蔡英文 03 152380 46.8805%
R
全部下載所有連結,然後把每個連結後面的發言存到自己的電腦。參考台大新聞所謝吉隆教授撰寫的語法:query = "指南宮"
pre <- "https://www.ptt.cc"
url <- str_c("https://www.ptt.cc/bbs/gossiping/search?page=", 1, "&q=", query)
post.df <- data_frame()
for(page in 1:8){
url <- str_c("https://www.ptt.cc/bbs/gossiping/search?page=", page, "&q=", query)
print(url)
doc <- GET(url, config = set_cookies("over18" = "1")) %>%
content("text") %>%
read_html()
nodes <- doc %>% html_nodes(".r-ent")
nrec <- nodes %>% html_node(".nrec span") %>% html_text() %>% as.numeric()
title <- nodes %>% html_node(".title a") %>% html_text()
link <- nodes %>% html_node(".title a") %>% html_attr("href") %>%
str_c(pre, .)
author <- nodes %>% html_node(".meta .author") %>% html_text()
page.df <- data_frame(nrec, title, link, author)
post.df <- bind_rows(post.df, page.df)
#print(nrow(post.df))
}
## [1] "https://www.ptt.cc/bbs/gossiping/search?page=1&q=指南宮"
## [1] "https://www.ptt.cc/bbs/gossiping/search?page=2&q=指南宮"
## [1] "https://www.ptt.cc/bbs/gossiping/search?page=3&q=指南宮"
## [1] "https://www.ptt.cc/bbs/gossiping/search?page=4&q=指南宮"
## [1] "https://www.ptt.cc/bbs/gossiping/search?page=5&q=指南宮"
## [1] "https://www.ptt.cc/bbs/gossiping/search?page=6&q=指南宮"
## [1] "https://www.ptt.cc/bbs/gossiping/search?page=7&q=指南宮"
## [1] "https://www.ptt.cc/bbs/gossiping/search?page=8&q=指南宮"
#View data
head(post.df)
## # A tibble: 2 × 4
## nrec title link author
## <dbl> <chr> <chr> <chr>
## 1 2 [新聞] 赴指南宮參拜祈福 蕭美琴:盼正能量遍全 https://www.ptt.cc… seiya…
## 2 2 Re: 有哪些是情侶不能去的觀光地啊→關於指南宮? https://www.ptt.cc… ck517
R
可以根據統計模型或者數學模型繪圖,也可以結合地理資訊繪圖。#install.packages(c("maps", "mapdata", "ggplot2"))
# Load necessary libraries
library(ggplot2)
library(maps)
library(mapdata)
# Extract Taiwan map data
taiwan <- map_data("world", region = "Taiwan")
# Define the coordinates of six metropolitan cities
metropolitan_cities <- data.frame(
city = c("Taipei", "New Taipei", "Taichung", "Tainan", "Kaohsiung", "Taoyuan"),
lon = c(121.5654, 121.4619, 120.6700, 120.2790, 120.3120, 121.2168),
lat = c(25.0320, 25.0160, 24.1477, 22.9997, 22.6273, 24.9936)
)
# Plot the map of Taiwan
ggplot() +
geom_polygon(data = taiwan, aes(x = long, y = lat, group = group), fill = "grey80", color = "black") +
geom_point(data = metropolitan_cities, aes(x = lon, y = lat), size = 3, color = "red") +
geom_text(data = metropolitan_cities, aes(x = lon, y = lat, label = city), vjust = -0.5, size = 3, color = "black") +
labs(title = "Map of Taiwan with Six Metropolitan Cities") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5))
R
可以畫出某個X範圍的圖形:# Load necessary libraries
library(ggplot2)
# Define the function
f <- function(x) 2*x^2 + 1
# Generate x values
x <- seq(-5, 5, length.out = 100)
# Generate y values
y <- f(x)
# Create a data frame with x and y values
df <- data.frame(x = x, y = y)
# Plot the function
ggplot(df, aes(x, y)) +
geom_line(color = "blue") +
labs(title = "Plot of f(x) = 2x^2 + 1") +
xlab("x") +
ylab("f(x)") +
theme_minimal()
R
可以處理最簡單的數學到微積分,只要給它正確的函數,它就能計算微積分的結果。例如:#install.packages("Deriv")
library(Deriv)
# Define the function
f <- expression(x^3 + 2*x^2 + 9*x)
# Differentiate the function with respect to x
df_dx <- Deriv(f, "x")
# Print the result
print(df_dx)
## expression(9 + x * (3 * x + 4))
R
做html, LaTex等文件,並且結合來自統計模型的圖形以及表格。R
的語法,從讀取資料到操作,複製貼上語法即可得到希望的結果。R
的時間,但是希望同學自己寫程式,而不是依賴ChatGPT,才能真正判斷ChatGPT所提供的內容。## 最後更新日期 02/08/2025