今日學習主題:數據整理與清洗(二)

核心目標

掌握dplyrtidyr包的高級數據操作,能夠靈活處理複雜數據。


一、dplyr 高級操作

1. 條件篩選與變形

# 示例數據
df <- tibble(
  id = 1:10,
  value = c(5, 15, -3, 8, 20, -7, 12, 9, -1, 6),
  category = rep(c("A", "B"), each = 5)
)

# 條件創建新變量
df <- df %>%
  mutate(
    value_category = case_when(
      value < 0 ~ "Negative",
      value >= 0 & value < 10 ~ "Low",
      value >= 10 ~ "High",
      TRUE ~ "Other"
    ),
    scaled_value = ifelse(value > 0, log(value + 1), value)  # 對正數取對數
  )

2. 跨列操作

# 創建寬數據
df_wide <- tibble(
  id = 1:5,
  sales_2020 = c(100, 150, 80, 200, 90),
  sales_2021 = c(120, 160, 85, 220, 95),
  sales_2022 = c(130, 170, 90, 240, 100)
)

# 計算每年的增長率(跨列操作)
df_wide <- df_wide %>%
  mutate(
    growth_2021 = (sales_2021 - sales_2020) / sales_2020 * 100,
    growth_2022 = (sales_2022 - sales_2021) / sales_2021 * 100
  )

# 使用across()進行批量操作
df_wide <- df_wide %>%
  mutate(across(starts_with("sales"), ~ round(. / max(.) * 100, 2), .names = "scaled_{.col}"))

二、tidyr 高級數據變形

1. 複雜數據的寬長轉換

# 創建複雜數據
complex_df <- tibble(
  student = rep(c("Alice", "Bob"), each = 2),
  subject = rep(c("Math", "English"), times = 2),
  score_midterm = c(85, 78, 92, 88),
  score_final = c(88, 80, 95, 85),
  attendance = c(95, 90, 98, 92)
)

# 轉換為長數據
long_df <- complex_df %>%
  pivot_longer(
    cols = c(score_midterm, score_final, attendance),
    names_to = "metric_type",
    values_to = "value"
  )

# 分離指標類型
long_df <- long_df %>%
  separate(metric_type, into = c("metric", "period"), sep = "_", fill = "right")

2. 嵌套數據框

# 創建嵌套數據
nested_data <- df %>%
  group_by(category) %>%
  nest() %>%
  mutate(
    summary = map(data, ~ tibble(
      mean = mean(.x$value),
      sd = sd(.x$value),
      n = nrow(.x)
    ))
  )

# 展開嵌套數據
unnested_data <- nested_data %>%
  unnest_wider(summary)

三、數據處理管道的高級應用

1. 條件管道操作

# 根據條件決定是否執行某步驟
process_data <- function(data, remove_negatives = TRUE) {
  data %>%
    {if(remove_negatives) filter(., value >= 0) else .} %>%
    mutate(
      category = factor(category),
      value_group = cut(value, breaks = 3, labels = c("Low", "Medium", "High"))
    )
}

2. 多數據集操作

# 創建多個相關數據集
sales_data <- tibble(
  id = 1:5,
  product = c("A", "B", "C", "A", "B"),
  sales = c(100, 200, 150, 120, 180)
)

price_data <- tibble(
  product = c("A", "B", "C"),
  price = c(10, 20, 15)
)

# 合併並計算總價值
combined <- sales_data %>%
  left_join(price_data, by = "product") %>%
  mutate(total_value = sales * price) %>%
  group_by(product) %>%
  summarise(total_sales = sum(sales), total_revenue = sum(total_value))

四、實際案例:電商數據清洗

# 模擬電商數據
set.seed(123)
ecommerce_data <- tibble(
  order_id = 1:100,
  customer_id = sample(1:20, 100, replace = TRUE),
  product = sample(c("Laptop", "Phone", "Tablet", "Headphones"), 100, replace = TRUE),
  price = round(runif(100, 50, 1000), 2),
  quantity = sample(1:5, 100, replace = TRUE),
  order_date = sample(seq(as.Date('2023-01-01'), as.Date('2023-12-31'), by="day"), 100)
)

# 數據清洗與分析
cleaned_data <- ecommerce_data %>%
  # 處理異常值
  mutate(
    price = ifelse(price > 2000, NA, price),  # 價格超過2000設為NA
    quantity = ifelse(quantity > 10, 1, quantity)  # 數量異常調整為1
  ) %>%
  # 計算衍生變量
  mutate(
    total_value = price * quantity,
    month = format(order_date, "%Y-%m"),
    weekday = weekdays(order_date)
  ) %>%
  # 分組分析
  group_by(product, month) %>%
  summarise(
    total_quantity = sum(quantity, na.rm = TRUE),
    total_revenue = sum(total_value, na.rm = TRUE),
    avg_price = mean(price, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  # 計算月度增長率
  group_by(product) %>%
  arrange(month) %>%
  mutate(
    revenue_growth = (total_revenue - lag(total_revenue)) / lag(total_revenue) * 100
  )

五、今日實踐任務

  1. 任務1:使用case_when()創建更復雜的條件變量
  • 對數值變量進行多級分類
  • 根據多個條件組合創建新變量
  1. 任務2:處理寬表數據
  • 將包含多個年份/月份指標的寬錶轉換為長表
  • 從長錶轉換回寬表,但使用不同的結構
  1. 任務3:實現數據清洗管道
  • 創建一個函數,接受數據和參數,執行完整的數據清洗流程
  • 包括異常值處理、缺失值插補、變量轉換等步驟
  1. 任務4:分析嵌套數據
  • 對分組後的數據應用不同的彙總函數
  • 使用map()系列函數對每個子集進行建模或分析

六、學習建議

  1. 理解數據思維:數據整理不僅是技術操作,更是理解數據結構和分析需求的過程
  2. 代碼可讀性:寫管道時適當換行和註釋,保持代碼清晰
  3. 錯誤處理:在關鍵步驟添加數據驗證,確保處理過程正確
  4. 性能考慮:對於大數據,考慮使用data.tabledtplyr

七、擴展學習(可選)

  1. 學習purrr包的高級迭代函數
  2. 瞭解furrr包進行並行處理
  3. 探索recipes包進行更復雜的數據預處理

今天的內容將幫助你建立更強大的數據處理能力。明天我們將開始數據可視化(ggplot2)的深入學習,將整理好的數據轉化為有意義的圖表。

堅持就是勝利!你已經完成了17天的學習,離掌握R語言又近了一步!