📚 今日目標

  1. 學習多種數據格式的導入導出
  2. 掌握數據清洗的基本操作
  3. 處理缺失值和異常值
  4. 實踐數據轉換和整理

📁 第一部分:數據導入

1.1 內置數據集

# 查看所有內置數據集
data()

# 加載內置數據集
data(mtcars)      # 汽車數據集
data(iris)        # 鳶尾花數據集
data(airquality)  # 空氣質量數據集

# 查看數據集信息
str(mtcars)       # 結構
dim(mtcars)       # 維度
names(mtcars)     # 列名
head(mtcars)      # 前6行

1.2 讀取文本文件

# 設置工作目錄(確保文件在此目錄下)
setwd("D:/R_learning")  # Windows
# setwd("/Users/username/R_learning")  # Mac/Linux

# 查看當前工作目錄
getwd()

# 讀取CSV文件
# 方法1:基礎R函數
sales_data <- read.csv("sales_data.csv", 
                      header = TRUE,        # 第一行是列名
                      stringsAsFactors = FALSE)  # 字符不轉為因子

# 方法2:readr包(更快更靈活)
install.packages("readr")  # 首次需要安裝
library(readr)
sales_data <- read_csv("sales_data.csv")

# 讀取製表符分隔文件
data_tab <- read.delim("data.txt", sep = "\t")

# 讀取帶編碼的文件(處理中文)
data_chinese <- read.csv("data.csv", fileEncoding = "UTF-8")

1.3 讀取Excel文件

# 方法1:readxl包(推薦)
install.packages("readxl")
library(readxl)

# 讀取第一個工作表
excel_data <- read_excel("data.xlsx")

# 讀取指定工作表
excel_data <- read_excel("data.xlsx", sheet = "Sheet2")

# 讀取指定範圍
excel_data <- read_excel("data.xlsx", range = "A1:D100")

# 方法2:openxlsx包
install.packages("openxlsx")
library(openxlsx)
excel_data <- read.xlsx("data.xlsx")

1.4 讀取其他格式

# 讀取SPSS數據
install.packages("haven")
library(haven)
spss_data <- read_sav("data.sav")

# 讀取Stata數據
stata_data <- read_dta("data.dta")

# 讀取JSON數據
install.packages("jsonlite")
library(jsonlite)
json_data <- fromJSON("data.json")

# 讀取網頁數據
install.packages("rvest")
library(rvest)
web_data <- read_html("http://example.com") %>%
  html_table()

💾 第二部分:數據導出

2.1 導出為CSV

# 基礎R函數
write.csv(mtcars, "mtcars_export.csv", 
          row.names = FALSE,  # 不保存行名
          fileEncoding = "UTF-8")

# readr包函數(更快)
library(readr)
write_csv(mtcars, "mtcars_export.csv")

# 導出為製表符分隔
write.table(mtcars, "mtcars.txt", 
           sep = "\t", 
           row.names = FALSE)

2.2 導出為Excel

# openxlsx包
library(openxlsx)
write.xlsx(mtcars, "mtcars_export.xlsx")

# 導出多個工作表
wb <- createWorkbook()
addWorksheet(wb, "mtcars_data")
writeData(wb, "mtcars_data", mtcars)
addWorksheet(wb, "summary")
writeData(wb, "summary", summary(mtcars))
saveWorkbook(wb, "export.xlsx", overwrite = TRUE)

🧹 第三部分:數據清洗基礎

3.1 查看數據概況

# 使用airquality數據集
data(airquality)

# 基本概況
summary(airquality)      # 統計摘要
str(airquality)          # 數據結構
head(airquality, 10)     # 前10行
tail(airquality)         # 後6行

# 更詳細的概況
install.packages("skimr")
library(skimr)
skim(airquality)

# 查看缺失值
sum(is.na(airquality))           # 總缺失值數
colSums(is.na(airquality))       # 每列缺失值數
complete.cases(airquality)       # 完整行

3.2 處理缺失值

# 識別缺失值
which(is.na(airquality$Ozone))  # 找到Ozone缺失的行號
airquality[is.na(airquality$Ozone), ]  # 查看這些行

# 方法1:刪除缺失值
clean_data <- na.omit(airquality)  # 刪除任何列有缺失的行
clean_data <- airquality[complete.cases(airquality), ]  # 同上

# 僅刪除Ozone缺失的行
clean_data <- airquality[!is.na(airquality$Ozone), ]

# 方法2:用均值/中位數填補
# 創建數據的副本
airquality_filled <- airquality

# 用均值填補Ozone缺失值
mean_ozone <- mean(airquality$Ozone, na.rm = TRUE)
airquality_filled$Ozone[is.na(airquality_filled$Ozone)] <- mean_ozone

# 用中位數填補Solar.R缺失值
median_solar <- median(airquality$Solar.R, na.rm = TRUE)
airquality_filled$Solar.R[is.na(airquality_filled$Solar.R)] <- median_solar

# 方法3:使用插值法
install.packages("zoo")
library(zoo)
airquality$Ozone_interp <- na.approx(airquality$Ozone)  # 線性插值

3.3 處理異常值

# 識別異常值
# 使用IQR方法
find_outliers <- function(x) {
  Q1 <- quantile(x, 0.25, na.rm = TRUE)
  Q3 <- quantile(x, 0.75, na.rm = TRUE)
  IQR <- Q3 - Q1
  lower_bound <- Q1 - 1.5 * IQR
  upper_bound <- Q3 + 1.5 * IQR
  return(x < lower_bound | x > upper_bound)
}

# 檢測Ozone異常值
outliers <- find_outliers(airquality$Ozone)
airquality$Ozone[outliers]

# 處理異常值
# 方法1:替換為NA
airquality_clean <- airquality
airquality_clean$Ozone[outliers] <- NA

# 方法2:替換為邊界值
airquality_clean$Ozone <- ifelse(outliers, 
                                 median(airquality$Ozone, na.rm = TRUE),
                                 airquality$Ozone)

🔧 第四部分:數據轉換

4.1 數據篩選

# 基礎篩選
# 篩選Temp > 80的行
hot_days <- airquality[airquality$Temp > 80, ]

# 多個條件篩選
hot_windy <- airquality[airquality$Temp > 80 & airquality$Wind > 10, ]

# 使用subset函數
hot_days <- subset(airquality, Temp > 80)
hot_windy <- subset(airquality, Temp > 80 & Wind > 10)
high_ozone <- subset(airquality, Ozone > 100, select = c(Ozone, Temp, Month))

# dplyr包篩選(明天詳細學習)
library(dplyr)
filter(airquality, Temp > 80)

4.2 數據排序

# 單列排序
sorted_by_temp <- airquality[order(airquality$Temp), ]  # 升序
sorted_by_temp_desc <- airquality[order(-airquality$Temp), ]  # 降序

# 多列排序
sorted_multi <- airquality[order(airquality$Month, -airquality$Temp), ]

# 使用arrange函數(dplyr)
sorted_dplyr <- arrange(airquality, Month, desc(Temp))

4.3 數據類型轉換

# 創建示例數據
sample_data <- data.frame(
  id = 1:5,
  value = c("100", "200", "300", "400", "500"),
  category = c("A", "B", "A", "C", "B"),
  date_str = c("2023-01-01", "2023-01-02", "2023-01-03", "2023-01-04", "2023-01-05")
)

# 字符轉數值
sample_data$value_num <- as.numeric(sample_data$value)

# 字符轉因子
sample_data$category_fact <- as.factor(sample_data$category)

# 字符轉日期
sample_data$date <- as.Date(sample_data$date_str)

# 因子轉字符
sample_data$category_char <- as.character(sample_data$category_fact)

# 檢查類型
str(sample_data)

4.4 創建新變量

# 基於現有變量創建
airquality$Temp_C <- (airquality$Temp - 32) * 5/9  # 華氏轉攝氏

# 分類變量創建
airquality$Temp_level <- ifelse(airquality$Temp > 80, "High", 
                               ifelse(airquality$Temp > 70, "Medium", "Low"))

# 使用cut函數分段
airquality$Wind_group <- cut(airquality$Wind,
                            breaks = c(0, 5, 10, 15, 20, 25),
                            labels = c("0-5", "5-10", "10-15", "15-20", "20-25"))

# 查看新變量分佈
table(airquality$Temp_level)
table(airquality$Wind_group)

📊 實戰案例:銷售數據清洗

案例數據準備

# 創建模擬銷售數據
set.seed(123)  # 設置隨機種子,確保可重複性
sales <- data.frame(
  OrderID = 1:100,
  Customer = sample(c("Alice", "Bob", "Charlie", "David", "Eva"), 100, replace = TRUE),
  Product = sample(c("Laptop", "Phone", "Tablet", "Watch", "Headphones"), 100, replace = TRUE),
  Quantity = sample(1:10, 100, replace = TRUE),
  Price = round(runif(100, 100, 2000), 2),
  Date = seq.Date(as.Date("2023-01-01"), by = "day", length.out = 100),
  Region = sample(c("North", "South", "East", "West", NA), 100, replace = TRUE)
)

# 故意添加一些問題和缺失值
sales$Price[sample(1:100, 5)] <- NA  # 5個價格缺失
sales$Quantity[sample(1:100, 3)] <- -1  # 3個負數量
sales$Customer[sample(1:100, 2)] <- ""  # 2個空客户名

# 查看原始數據
head(sales)
summary(sales)

數據清洗流程

# 步驟1:查看數據概況
str(sales)
colSums(is.na(sales))

# 步驟2:處理缺失值
# 價格用中位數填補
sales$Price[is.na(sales$Price)] <- median(sales$Price, na.rm = TRUE)

# 地區用眾數填補
region_mode <- names(sort(table(sales$Region), decreasing = TRUE))[1]
sales$Region[is.na(sales$Region)] <- region_mode

# 步驟3:處理異常值
# 修正負數量
sales$Quantity[sales$Quantity < 0] <- abs(sales$Quantity[sales$Quantity < 0])

# 識別異常價格(使用IQR方法)
price_Q1 <- quantile(sales$Price, 0.25)
price_Q3 <- quantile(sales$Price, 0.75)
price_IQR <- price_Q3 - price_Q1
lower_bound <- price_Q1 - 1.5 * price_IQR
upper_bound <- price_Q3 + 1.5 * price_IQR

# 將異常價格替換為中位數
sales$Price[sales$Price < lower_bound | sales$Price > upper_bound] <- median(sales$Price)

# 步驟4:處理無效文本
# 刪除空客户名
sales <- sales[sales$Customer != "", ]

# 步驟5:創建新變量
# 計算總金額
sales$Total <- sales$Quantity * sales$Price

# 提取月份
sales$Month <- format(sales$Date, "%Y-%m")

# 創建價格等級
sales$Price_Level <- cut(sales$Price,
                        breaks = quantile(sales$Price, probs = c(0, 0.33, 0.66, 1)),
                        labels = c("Low", "Medium", "High"),
                        include.lowest = TRUE)

# 步驟6:保存清洗後的數據
write.csv(sales, "cleaned_sales_data.csv", row.names = FALSE)

💻 今日練習

練習1:數據導入與查看

# 1. 下載一個CSV數據集(可以從Kaggle或政府開放數據平台)
# 2. 使用不同方法導入數據
# 3. 查看數據的基本信息:維度、列名、類型、缺失值
# 4. 使用summary和skim函數了解數據分佈

練習2:數據清洗實踐

# 使用airquality數據集
# 1. 找出所有有缺失值的行
# 2. 用不同方法處理Ozone列的缺失值(刪除、均值填補、中位數填補)
# 3. 識別並處理Temp列的異常值
# 4. 創建一個新列,將Month轉換為季節(Spring:3-5, Summer:6-8等)

練習3:完整數據清洗流程

# 創建包含以下問題的模擬數據集:
# - 缺失值
# - 異常值
# - 數據類型錯誤
# - 不一致的文本數據
# 然後:
# 1. 識別所有數據質量問題
# 2. 制定清洗策略
# 3. 實施清洗步驟
# 4. 保存清洗後的數據

📌 今日總結

重點掌握:

  • ✓ 多種格式數據的導入導出
  • ✓ 數據質量的檢查和評估
  • ✓ 缺失值的識別和處理方法
  • ✓ 異常值的檢測和處理
  • ✓ 數據轉換和變量創建

常用函數回顧:

read.csv() / write.csv()    # CSV文件讀寫
read_excel()                # Excel文件讀取
str() / summary()           # 數據查看
is.na() / complete.cases()  # 缺失值處理
order() / subset()          # 排序和篩選
as.numeric() / as.Date()    # 類型轉換
ifelse() / cut()            # 條件判斷和分段

🎯 明日預告

第三天:dplyr數據整理與操作

  • dplyr包的核心函數
  • 管道操作符 %>%
  • 數據的分組與彙總
  • 數據的連接與合併

學習建議

  1. 實際下載一些真實數據集進行練習
  2. 數據清洗前先備份原始數據
  3. 記錄數據清洗的每一步操作和決策
  4. 嘗試使用不同的缺失值處理方法,比較結果差異

記得保存今天的代碼腳本為day2.R,明天見!🚀