📚 今日目標

  1. 掌握R函數編寫和調試技巧
  2. 學習函數式編程概念
  3. 掌握向量化操作和循環優化
  4. 學習代碼性能分析和優化
  5. 掌握代碼重構和最佳實踐

🏗️ 第一部分:函數基礎

1.1 函數定義與結構

# 基本函數結構
# function_name <- function(arguments) {
#   # 函數體
#   return(value)
# }

# 簡單示例
add_numbers <- function(x, y) {
  result <- x + y
  return(result)
}

# 調用函數
add_numbers(5, 3)
add_numbers(10, 20)

# 默認參數
calculate_area <- function(radius, pi = 3.14159) {
  area <- pi * radius^2
  return(area)
}

calculate_area(5)          # 使用默認pi值
calculate_area(5, 3.14)    # 指定pi值

# 多參數函數
create_person <- function(name, age, city = "未知") {
  person <- list(
    name = name,
    age = age,
    city = city,
    introduction = paste(name, ",", age, "歲,來自", city)
  )
  return(person)
}

person1 <- create_person("張三", 25, "北京")
person2 <- create_person("李四", 30)

1.2 參數檢查與驗證

# 參數類型檢查
safe_divide <- function(x, y) {
  # 參數檢查
  if (!is.numeric(x) || !is.numeric(y)) {
    stop("兩個參數都必須是數值型")
  }
  
  if (y == 0) {
    warning("除數不能為零,返回Inf")
    return(Inf)
  }
  
  return(x / y)
}

# 測試
safe_divide(10, 2)
safe_divide(10, 0)
# safe_divide("10", 2)  # 會拋出錯誤

# 參數驗證函數
validate_input <- function(data, type = "numeric", min_val = NULL, max_val = NULL) {
  # 檢查類型
  if (type == "numeric" && !is.numeric(data)) {
    stop("輸入必須是數值型")
  }
  
  if (type == "character" && !is.character(data)) {
    stop("輸入必須是字符型")
  }
  
  # 檢查範圍
  if (!is.null(min_val) && any(data < min_val)) {
    warning(paste("有些值小於最小值", min_val))
  }
  
  if (!is.null(max_val) && any(data > max_val)) {
    warning(paste("有些值大於最大值", max_val))
  }
  
  return(TRUE)
}

# 使用驗證
validate_input(c(1, 2, 3), "numeric", min_val = 0)
validate_input(c("a", "b", "c"), "character")

1.3 返回值與輸出

# 返回多個值
calculate_stats <- function(x) {
  if (!is.numeric(x)) {
    stop("輸入必須是數值向量")
  }
  
  stats <- list(
    mean = mean(x, na.rm = TRUE),
    median = median(x, na.rm = TRUE),
    sd = sd(x, na.rm = TRUE),
    min = min(x, na.rm = TRUE),
    max = max(x, na.rm = TRUE),
    n = length(x),
    n_missing = sum(is.na(x))
  )
  
  return(stats)
}

# 調用
data <- c(1, 2, 3, 4, 5, NA, 7, 8, 9)
result <- calculate_stats(data)
result$mean
result$sd

# 使用cat和print輸出信息
verbose_calculate <- function(x, verbose = TRUE) {
  if (verbose) {
    cat("開始計算統計量...\n")
    cat("數據長度:", length(x), "\n")
  }
  
  mean_val <- mean(x, na.rm = TRUE)
  
  if (verbose) {
    cat("計算完成\n")
    cat("平均值:", mean_val, "\n")
  }
  
  return(mean_val)
}

verbose_calculate(c(1, 2, 3))
verbose_calculate(c(1, 2, 3), verbose = FALSE)

# 返回不可見值
invisible_return <- function(x) {
  result <- x * 2
  invisible(result)  # 返回但不打印
}

temp <- invisible_return(5)
print(temp)  # 需要顯式打印才能看到

🔧 第二部分:函數式編程

2.1 apply函數族

# apply - 對矩陣或數組的行或列應用函數
mat <- matrix(1:12, nrow = 3, ncol = 4)

# 對每列求均值
apply(mat, 2, mean)  # 2表示列

# 對每行求和
apply(mat, 1, sum)   # 1表示行

# 自定義函數
apply(mat, 1, function(x) max(x) - min(x))  # 每行的極差

# lapply - 對列表應用函數,返回列表
my_list <- list(a = 1:5, b = 6:10, c = 11:15)

lapply(my_list, mean)           # 每個元素的均值
lapply(my_list, length)         # 每個元素的長度
lapply(my_list, summary)        # 每個元素的摘要統計

# 使用自定義函數
lapply(my_list, function(x) x[x > mean(x)])

# sapply - 簡化輸出為向量或矩陣
sapply(my_list, mean)           # 返回向量
sapply(my_list, range)          # 返回矩陣

# vapply - 指定返回類型,更安全
vapply(my_list, mean, numeric(1))  # 返回數值向量
vapply(my_list, length, integer(1)) # 返回整數向量

# tapply - 按因子分組應用函數
data <- data.frame(
  value = c(10, 15, 20, 25, 30, 35),
  group = factor(c("A", "A", "B", "B", "C", "C"))
)

tapply(data$value, data$group, mean)
tapply(data$value, data$group, function(x) c(mean = mean(x), sd = sd(x)))

2.2 purrr包函數式編程

# 安裝並加載purrr包
install.packages("purrr")
library(purrr)
library(dplyr)

# map系列函數(purrr的apply)
numbers <- list(1:5, 6:10, 11:15)

# map - 返回列表
map(numbers, mean)

# map_dbl - 返回數值向量
map_dbl(numbers, mean)

# map_int - 返回整數向量
map_int(numbers, length)

# map_chr - 返回字符向量
map_chr(numbers, paste, collapse = ",")

# map_df - 返回數據框
map_df(numbers, ~ data.frame(
  mean = mean(.x),
  sum = sum(.x),
  length = length(.x)
))

# 使用公式簡寫
map_dbl(numbers, ~ mean(.x) * 2)

# walk - 執行副作用操作(不返回值)
walk(numbers, ~ cat("長度:", length(.x), "\n"))

# 處理多個輸入
map2(1:3, 4:6, ~ .x + .y)  # 向量加法
pmap(list(1:3, 4:6, 7:9), ~ sum(c(...)))  # 多參數函數

# 安全函數(處理錯誤)
safe_mean <- safely(mean, otherwise = NA)

result <- list(1:5, "not numeric", 6:10) %>%
  map(safe_mean)

# 提取結果和錯誤
map(result, "result")    # 成功的結果
map(result, "error")     # 錯誤信息

# possibly - 發生錯誤時返回默認值
possibly_mean <- possibly(mean, otherwise = NA)
map(list(1:5, "not numeric", 6:10), possibly_mean)

2.3 高階函數

# 函數作為參數
apply_function <- function(f, x) {
  if (!is.function(f)) {
    stop("第一個參數必須是函數")
  }
  return(f(x))
}

apply_function(mean, c(1, 2, 3, 4, 5))
apply_function(sd, c(1, 2, 3, 4, 5))
apply_function(\(x) sum(x^2), c(1, 2, 3))  # 匿名函數

# 函數工廠(返回函數的函數)
create_multiplier <- function(factor) {
  function(x) {
    x * factor
  }
}

double <- create_multiplier(2)
triple <- create_multiplier(3)

double(10)  # 20
triple(10)  # 30

# 創建一系列轉換函數
create_scaler <- function(method = "standardize") {
  if (method == "standardize") {
    function(x) {
      (x - mean(x)) / sd(x)
    }
  } else if (method == "normalize") {
    function(x) {
      (x - min(x)) / (max(x) - min(x))
    }
  } else if (method == "robust") {
    function(x) {
      (x - median(x)) / IQR(x)
    }
  } else {
    stop("未知的標準化方法")
  }
}

std_scale <- create_scaler("standardize")
norm_scale <- create_scaler("normalize")

std_scale(c(1, 2, 3, 4, 5))
norm_scale(c(1, 2, 3, 4, 5))

# 記憶化(緩存函數結果)
library(memoise)

# 創建記憶化函數
slow_function <- function(x) {
  Sys.sleep(1)  # 模擬耗時操作
  return(x^2)
}

memoized_slow <- memoise(slow_function)

# 第一次調用會慢
system.time(memoized_slow(5))  # 約1秒

# 第二次調用會快(使用緩存)
system.time(memoized_slow(5))  # 幾乎0秒

⚡ 第三部分:性能優化

3.1 向量化操作

# 向量化 vs 循環
n <- 1000000
x <- runif(n)

# 循環方法(慢)
system.time({
  result_loop <- numeric(n)
  for (i in 1:n) {
    result_loop[i] <- x[i]^2 + sin(x[i])
  }
})

# 向量化方法(快)
system.time({
  result_vec <- x^2 + sin(x)
})

# 驗證結果
all.equal(result_loop, result_vec)

# 更多向量化示例
# 1. 數學運算
y <- x * 2 + 3
z <- exp(x) * log(x + 1)

# 2. 邏輯運算
logical_vec <- x > 0.5
count_true <- sum(logical_vec)  # 向量化計數

# 3. ifelse向量化
categorized <- ifelse(x < 0.33, "低",
                     ifelse(x < 0.66, "中", "高"))

# 4. 使用rowSums, colSums等
mat <- matrix(runif(10000), nrow = 100)
row_sums <- rowSums(mat)
col_means <- colMeans(mat)

# 避免不必要的向量化
# 有時簡單的循環可能更快
small_n <- 10
small_x <- 1:small_n

# 小數據時差異不大
system.time(for(i in 1:small_n) small_x[i]^2)
system.time(small_x^2)

3.2 循環優化

# 預分配內存
n <- 10000

# 不好的做法:動態擴展
system.time({
  bad_result <- c()
  for (i in 1:n) {
    bad_result <- c(bad_result, i^2)
  }
})

# 好的做法:預分配
system.time({
  good_result <- numeric(n)  # 預分配內存
  for (i in 1:n) {
    good_result[i] <- i^2
  }
})

# 使用適當的循環結構
# 計算矩陣每行的統計量
mat <- matrix(rnorm(10000), nrow = 100)

# 方法1:使用apply(推薦)
system.time({
  stats1 <- apply(mat, 1, function(row) {
    c(mean = mean(row), sd = sd(row), median = median(row))
  })
})

# 方法2:預分配+循環
system.time({
  n_rows <- nrow(mat)
  stats2 <- matrix(NA, nrow = n_rows, ncol = 3)
  colnames(stats2) <- c("mean", "sd", "median")
  
  for (i in 1:n_rows) {
    row <- mat[i, ]
    stats2[i, ] <- c(mean(row), sd(row), median(row))
  }
})

# 方法3:向量化計算
system.time({
  means <- rowMeans(mat)
  sds <- apply(mat, 1, sd)  # rowSds需要matrixStats包
  medians <- apply(mat, 1, median)
  stats3 <- cbind(mean = means, sd = sds, median = medians)
})

# 使用Rcpp進行C++級別的循環優化
# install.packages("Rcpp")
library(Rcpp)

# 定義C++函數
cppFunction('
NumericVector square_cpp(NumericVector x) {
  int n = x.size();
  NumericVector result(n);
  
  for(int i = 0; i < n; ++i) {
    result[i] = x[i] * x[i];
  }
  return result;
}
')

# 比較性能
x <- rnorm(1000000)
system.time(x^2)          # 向量化R
system.time(square_cpp(x)) # C++函數

3.3 內存管理

# 監控內存使用
library(pryr)

# 查看對象大小
x <- rnorm(1000000)
object_size(x)  # 約8MB

# 比較不同數據結構的內存使用
vec <- 1:1000000
list_ <- as.list(1:1000000)

object_size(vec)   # 約4MB
object_size(list_) # 約32MB

# 內存清理
# 查看當前內存中的對象
ls()

# 刪除不需要的對象
rm(x, vec, list_)
gc()  # 強制垃圾回收

# 使用memory.size和memory.limit(Windows)
if (.Platform$OS.type == "windows") {
  memory.size()    # 當前使用內存
  memory.limit()   # 內存限制
  memory.limit(size = 8000)  # 增加內存限制到8GB
}

# 大數據集處理技巧
# 1. 使用data.table代替data.frame
install.packages("data.table")
library(data.table)

# 創建大數據集
n <- 1000000
big_df <- data.frame(
  id = 1:n,
  value = rnorm(n),
  category = sample(letters[1:10], n, replace = TRUE)
)

big_dt <- as.data.table(big_df)

# 比較內存使用
object_size(big_df)
object_size(big_dt)

# 2. 使用ff或bigmemory包處理超大文件
install.packages("bigmemory")
library(bigmemory)

# 創建大矩陣
big_mat <- big.matrix(nrow = 10000, ncol = 1000, 
                      init = 0, 
                      backingfile = "big_mat.bin",
                      descriptorfile = "big_mat.desc")

# 3. 分塊處理
process_in_chunks <- function(data, chunk_size = 10000, fun) {
  n <- nrow(data)
  chunks <- ceiling(n / chunk_size)
  results <- list()
  
  for (i in 1:chunks) {
    start <- (i - 1) * chunk_size + 1
    end <- min(i * chunk_size, n)
    chunk <- data[start:end, ]
    results[[i]] <- fun(chunk)
  }
  
  return(do.call(rbind, results))
}

# 示例:分塊計算均值
chunk_means <- process_in_chunks(big_df, chunk_size = 50000, 
                                 function(chunk) {
                                   colMeans(chunk[, c("id", "value")])
                                 })

📊 第四部分:代碼性能分析

4.1 性能分析工具

# 使用system.time測量執行時間
system.time({
  # 需要測量的代碼
  x <- rnorm(1000000)
  y <- x^2 + sin(x)
})

# 使用microbenchmark進行基準測試
install.packages("microbenchmark")
library(microbenchmark)

# 比較不同方法的性能
compare_speed <- microbenchmark(
  循環 = {
    result <- numeric(1000)
    for(i in 1:1000) {
      result[i] <- i^2
    }
  },
  向量化 = {
    result <- (1:1000)^2
  },
  sapply = {
    result <- sapply(1:1000, function(x) x^2)
  },
  times = 100  # 每個方法運行100次
)

print(compare_speed)

# 可視化比較結果
library(ggplot2)
autoplot(compare_speed)

# 使用profvis進行代碼剖析
install.packages("profvis")
library(profvis)

# 啓動性能分析
profvis({
  # 分析的代碼
  n <- 10000
  mat <- matrix(rnorm(n * 100), nrow = n)
  
  # 方法1:循環
  result1 <- matrix(NA, nrow = n, ncol = 3)
  for (i in 1:n) {
    result1[i, ] <- c(mean(mat[i, ]), sd(mat[i, ]), median(mat[i, ]))
  }
  
  # 方法2:apply
  result2 <- t(apply(mat, 1, function(row) {
    c(mean(row), sd(row), median(row))
  }))
})

# 使用bench包進行更詳細的基準測試
install.packages("bench")
library(bench)

bm <- bench::mark(
  循環 = {
    result <- numeric(1000)
    for(i in 1:1000) {
      result[i] <- sqrt(i)
    }
  },
  向量化 = sqrt(1:1000),
  迭代次數 = 1000
)

print(bm)
plot(bm)

4.2 代碼重構示例

# 原始代碼(效率較低)
calculate_statistics_original <- function(data) {
  n <- nrow(data)
  results <- data.frame(
    mean = numeric(n),
    sd = numeric(n),
    min = numeric(n),
    max = numeric(n)
  )
  
  for (i in 1:n) {
    row <- data[i, ]
    results$mean[i] <- mean(row, na.rm = TRUE)
    results$sd[i] <- sd(row, na.rm = TRUE)
    results$min[i] <- min(row, na.rm = TRUE)
    results$max[i] <- max(row, na.rm = TRUE)
  }
  
  return(results)
}

# 重構後的代碼(使用向量化)
calculate_statistics_optimized <- function(data) {
  # 使用apply進行向量化計算
  means <- apply(data, 1, mean, na.rm = TRUE)
  sds <- apply(data, 1, sd, na.rm = TRUE)
  mins <- apply(data, 1, min, na.rm = TRUE)
  maxs <- apply(data, 1, max, na.rm = TRUE)
  
  results <- data.frame(
    mean = means,
    sd = sds,
    min = mins,
    max = maxs
  )
  
  return(results)
}

# 進一步優化(使用矩陣運算)
calculate_statistics_fast <- function(data) {
  # 轉換為矩陣
  mat <- as.matrix(data)
  
  # 使用行操作
  means <- rowMeans(mat, na.rm = TRUE)
  
  # 使用matrixStats包獲取更快的行統計
  if (requireNamespace("matrixStats", quietly = TRUE)) {
    library(matrixStats)
    sds <- rowSds(mat, na.rm = TRUE)
    mins <- rowMins(mat, na.rm = TRUE)
    maxs <- rowMaxs(mat, na.rm = TRUE)
  } else {
    # 回退到apply
    sds <- apply(mat, 1, sd, na.rm = TRUE)
    mins <- apply(mat, 1, min, na.rm = TRUE)
    maxs <- apply(mat, 1, max, na.rm = TRUE)
  }
  
  data.frame(mean = means, sd = sds, min = mins, max = maxs)
}

# 性能比較
test_data <- matrix(rnorm(1000 * 100), nrow = 1000)

bench_results <- microbenchmark(
  原始 = calculate_statistics_original(test_data),
  優化 = calculate_statistics_optimized(test_data),
  快速 = calculate_statistics_fast(test_data),
  times = 10
)

print(bench_results)

🎯 第五部分:最佳實踐

5.1 代碼風格指南

# 1. 命名規範
# 變量名:小寫,用下劃線分隔
student_age <- 20
average_score <- 85.5
data_file_path <- "/path/to/data.csv"

# 函數名:動詞開頭,描述操作
calculate_mean <- function(x) mean(x)
prepare_data <- function(data) {
  # 數據處理
}
validate_input <- function(input) {
  # 輸入驗證
}

# 2. 註釋規範
# 文件頭註釋
# 文件名: data_analysis.R
# 作者: 你的名字
# 創建日期: 2024-01-15
# 描述: 數據分析主腳本

# 函數註釋
#' 計算數據的描述性統計量
#'
#' @param data 數值向量或矩陣
#' @param na.rm 是否移除NA值,默認為TRUE
#' @return 包含均值、標準差等統計量的列表
#' @examples
#' calculate_descriptive_stats(c(1, 2, 3, 4, 5))
calculate_descriptive_stats <- function(data, na.rm = TRUE) {
  # 函數體
}

# 3. 代碼格式化
# 使用一致的空格和縮進
good_format <- function(x, y) {
  result <- x + y
  
  if (result > 100) {
    return("很大")
  } else {
    return("不大")
  }
}

# 4. 錯誤處理
robust_function <- function(input) {
  # 參數驗證
  if (!is.numeric(input)) {
    stop("輸入必須是數值型")
  }
  
  # 嘗試執行
  tryCatch({
    result <- log(input)
    return(result)
  }, error = function(e) {
    warning("計算對數時出錯: ", e$message)
    return(NA)
  })
}

# 5. 使用管道提高可讀性
library(dplyr)

# 不好的寫法
result <- summarize(
  filter(
    group_by(mtcars, cyl),
    mpg > 20
  ),
  avg_hp = mean(hp)
)

# 好的寫法(使用管道)
result <- mtcars %>%
  group_by(cyl) %>%
  filter(mpg > 20) %>%
  summarize(avg_hp = mean(hp))

5.2 模塊化編程

# 創建工具函數模塊
# utils.R - 工具函數

#' 數據標準化函數
#' 
#' @param x 數值向量
#' @param method 標準化方法:"zscore", "minmax", "robust"
#' @return 標準化後的向量
scale_data <- function(x, method = "zscore") {
  if (method == "zscore") {
    (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE)
  } else if (method == "minmax") {
    (x - min(x, na.rm = TRUE)) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
  } else if (method == "robust") {
    (x - median(x, na.rm = TRUE)) / IQR(x, na.rm = TRUE)
  } else {
    stop("未知的標準化方法")
  }
}

#' 異常值檢測
#' 
#' @param x 數值向量
#' @param method 檢測方法:"iqr", "sd"
#' @param threshold 閾值
#' @return 邏輯向量,TRUE表示異常值
detect_outliers <- function(x, method = "iqr", threshold = 1.5) {
  if (method == "iqr") {
    q1 <- quantile(x, 0.25, na.rm = TRUE)
    q3 <- quantile(x, 0.75, na.rm = TRUE)
    iqr <- q3 - q1
    x < (q1 - threshold * iqr) | x > (q3 + threshold * iqr)
  } else if (method == "sd") {
    mu <- mean(x, na.rm = TRUE)
    sigma <- sd(x, na.rm = TRUE)
    abs(x - mu) > threshold * sigma
  } else {
    stop("未知的異常值檢測方法")
  }
}

# 創建分析模塊
# analysis.R - 分析函數

#' 執行完整數據分析流程
#' 
#' @param data 輸入數據框
#' @param target_var 目標變量名
#' @param predictor_vars 預測變量名向量
#' @return 分析結果列表
run_analysis <- function(data, target_var, predictor_vars) {
  # 數據清洗
  clean_data <- clean_dataset(data)
  
  # 描述性統計
  desc_stats <- calculate_descriptive_stats(clean_data)
  
  # 可視化
  plots <- create_visualizations(clean_data, target_var, predictor_vars)
  
  # 建模
  model <- build_model(clean_data, target_var, predictor_vars)
  
  # 返回結果
  list(
    data = clean_data,
    descriptive_stats = desc_stats,
    plots = plots,
    model = model
  )
}

# 主腳本
# main.R - 主程序

# 加載模塊
source("utils.R")
source("analysis.R")

# 加載數據
data <- read.csv("data.csv")

# 運行分析
results <- run_analysis(
  data = data,
  target_var = "price",
  predictor_vars = c("size", "rooms", "location")
)

# 輸出結果
print(results$descriptive_stats)
print(results$model$summary)

5.3 測試與調試

# 單元測試
# 使用testthat包
install.packages("testthat")
library(testthat)

# 創建測試文件
# test_utils.R

test_that("scale_data函數正常工作", {
  # 測試1: zscore標準化
  x <- c(1, 2, 3, 4, 5)
  scaled <- scale_data(x, "zscore")
  expect_equal(mean(scaled), 0, tolerance = 1e-10)
  expect_equal(sd(scaled), 1, tolerance = 1e-10)
  
  # 測試2: minmax標準化
  scaled_minmax <- scale_data(x, "minmax")
  expect_equal(min(scaled_minmax), 0, tolerance = 1e-10)
  expect_equal(max(scaled_minmax), 1, tolerance = 1e-10)
  
  # 測試3: 錯誤輸入
  expect_error(scale_data(x, "unknown_method"))
})

test_that("detect_outliers函數正常工作", {
  x <- c(1, 2, 3, 4, 5, 100)  # 100是異常值
  
  outliers_iqr <- detect_outliers(x, "iqr")
  outliers_sd <- detect_outliers(x, "sd", threshold = 3)
  
  expect_true(outliers_iqr[6])  # 第6個元素是異常值
  expect_false(all(outliers_iqr[1:5]))  # 前5個不是異常值
  
  expect_true(outliers_sd[6])
})

# 運行測試
test_dir("tests/")

# 調試技巧
debug_function <- function(x, y) {
  # 添加調試點
  browser()  # 在此處進入調試模式
  
  result <- x + y
  
  # 條件調試
  if (result > 100) {
    browser()  # 只有結果大於100時調試
  }
  
  return(result)
}

# 使用debug()函數
debug(calculate_mean)
calculate_mean(c(1, 2, 3))  # 進入調試模式
undebug(calculate_mean)     # 退出調試模式

# 跟蹤執行
trace("calculate_mean", quote(cat("計算均值中...\n")))
calculate_mean(c(1, 2, 3))
untrace("calculate_mean")

# 使用recover進行錯誤調試
options(error = recover)  # 發生錯誤時進入調試模式

# 日誌記錄
setup_logging <- function(log_file = "analysis.log") {
  log_file <<- file(log_file, open = "a")
  
  # 自定義消息函數
  log_message <- function(level, message) {
    timestamp <- format(Sys.time(), "%Y-%m-%d %H:%M:%S")
    cat(sprintf("[%s] [%s] %s\n", timestamp, level, message), 
        file = log_file, append = TRUE)
  }
  
  list(
    info = function(msg) log_message("INFO", msg),
    warn = function(msg) log_message("WARN", msg),
    error = function(msg) log_message("ERROR", msg)
  )
}

# 使用日誌
logger <- setup_logging()
logger$info("分析開始")
logger$warn("發現缺失值")
logger$error("計算失敗")

close(log_file)

🏭 第六部分:實戰案例

案例1:優化數據分析流水線

# 初始版本(需要優化)
process_data_slow <- function(file_path) {
  # 讀取數據
  data <- read.csv(file_path)
  
  # 數據清洗
  cleaned_data <- data.frame()
  for (i in 1:nrow(data)) {
    row <- data[i, ]
    # 處理缺失值
    for (j in 1:ncol(row)) {
      if (is.na(row[j])) {
        row[j] <- mean(data[, j], na.rm = TRUE)
      }
    }
    cleaned_data <- rbind(cleaned_data, row)
  }
  
  # 計算統計量
  stats <- list()
  for (col in names(cleaned_data)) {
    if (is.numeric(cleaned_data[[col]])) {
      col_data <- cleaned_data[[col]]
      stats[[col]] <- list(
        mean = mean(col_data),
        sd = sd(col_data),
        min = min(col_data),
        max = max(col_data)
      )
    }
  }
  
  return(list(data = cleaned_data, stats = stats))
}

# 優化版本
process_data_fast <- function(file_path) {
  # 使用data.table快速讀取
  library(data.table)
  
  # 1. 高效讀取
  data <- fread(file_path)
  
  # 2. 向量化處理缺失值
  impute_missing <- function(x) {
    if (is.numeric(x)) {
      x[is.na(x)] <- mean(x, na.rm = TRUE)
    } else {
      # 對於分類變量,用眾數填補
      if (any(is.na(x))) {
        freq_table <- table(x)
        mode_value <- names(freq_table)[which.max(freq_table)]
        x[is.na(x)] <- mode_value
      }
    }
    return(x)
  }
  
  cleaned_data <- lapply(data, impute_missing)
  cleaned_data <- as.data.table(cleaned_data)
  
  # 3. 使用矩陣運算計算統計量
  numeric_cols <- sapply(cleaned_data, is.numeric)
  numeric_data <- cleaned_data[, ..numeric_cols]
  
  if (ncol(numeric_data) > 0) {
    # 使用colMeans等向量化函數
    stats <- list(
      means = colMeans(as.matrix(numeric_data), na.rm = TRUE),
      sds = apply(numeric_data, 2, sd, na.rm = TRUE),
      mins = apply(numeric_data, 2, min, na.rm = TRUE),
      maxs = apply(numeric_data, 2, max, na.rm = TRUE)
    )
    
    # 轉換為數據框格式
    stats_df <- data.frame(
      variable = names(numeric_data),
      mean = stats$means,
      sd = stats$sds,
      min = stats$mins,
      max = stats$maxs,
      row.names = NULL
    )
  } else {
    stats_df <- NULL
  }
  
  # 4. 使用並行處理加速(如果數據很大)
  if (nrow(cleaned_data) > 100000) {
    library(parallel)
    n_cores <- detectCores() - 1
    
    # 並行計算相關性
    parallel_stats <- mclapply(
      numeric_data,
      function(x) {
        list(
          mean = mean(x, na.rm = TRUE),
          sd = sd(x, na.rm = TRUE)
        )
      },
      mc.cores = n_cores
    )
  }
  
  return(list(
    data = cleaned_data,
    stats = stats_df,
    n_rows = nrow(cleaned_data),
    n_cols = ncol(cleaned_data),
    processed_time = Sys.time()
  ))
}

# 性能比較
library(microbenchmark)

# 創建測試數據
create_test_data <- function(n_rows, n_cols) {
  data <- matrix(rnorm(n_rows * n_cols), nrow = n_rows)
  # 添加一些缺失值
  data[sample(1:length(data), length(data) * 0.1)] <- NA
  colnames(data) <- paste0("var", 1:n_cols)
  write.csv(data, "test_data.csv", row.names = FALSE)
}

# 創建中等大小數據集
create_test_data(10000, 50)

# 比較性能(注意:慢版本可能需要很長時間)
bench_results <- microbenchmark(
  快速版本 = process_data_fast("test_data.csv"),
  times = 10
)

print(bench_results)

# 清理測試文件
file.remove("test_data.csv")

案例2:創建可重用的分析框架

# analysis_framework.R
# 一個可重用的數據分析框架

#' 數據分析框架主類
AnalysisFramework <- R6::R6Class(
  "AnalysisFramework",
  
  public = list(
    # 字段
    data = NULL,
    config = NULL,
    results = NULL,
    logs = list(),
    
    # 初始化方法
    initialize = function(data = NULL, config = list()) {
      self$data <- data
      self$config <- private$default_config()
      self$update_config(config)
      private$log("INFO", "分析框架初始化完成")
    },
    
    # 更新配置
    update_config = function(new_config) {
      for (name in names(new_config)) {
        self$config[[name]] <- new_config[[name]]
      }
      invisible(self)
    },
    
    # 加載數據
    load_data = function(file_path, format = "auto") {
      private$log("INFO", paste("加載數據:", file_path))
      
      if (format == "csv" || (format == "auto" && grepl("\\.csv$", file_path))) {
        self$data <- private$read_csv(file_path)
      } else if (format == "excel" || (format == "auto" && grepl("\\.xlsx$", file_path))) {
        self$data <- private$read_excel(file_path)
      } else {
        stop("不支持的文件格式")
      }
      
      private$log("INFO", paste("數據加載完成,維度:", 
                               n