缘由

生信之路,道阻且长,记录经验,但渡有缘人。

碎碎念

及时当勉励,岁月不饶人 ——陶渊明

代码

在日常的数据分析中,我们经常会遇到以下需求:

  • 判断 NA / NaN / 特殊字符并过滤
  • 过滤某分组中全为 NA 的行
  • 选择多列执行同一个函数
  • 对多列执行多个函数

1. 基础模板:R 脚本加载的常用框架

#!/usr/bin/env Rscript 
 
suppressMessages({
    library(argparse)
    library(tidyverse)
    library(openxlsx)
    library(data.table)
    library(janitor)
 
    # 统计
    library(rstatix)
    
    # 可视化
    library(ggplot2)
    library(ggsci)
    library(ggpubr)
    library(patchwork)
 
    # 日志
    library(log4r)
})
 
options(stringsAsFactors = FALSE)
 
.logger <- create.logger(logfile = stdout(), level = "INFO")
 
warn2 <- function(message) {
    warn(.logger, message)
}

🍃 2. 判断 NA / NaN / 特殊值并过滤

实际数据中常出现:

  • NA
  • NaN
  • "Filtered"(某些仪器或软件生成的字符串)

下面写一个函数统一过滤:

is_valid <- function(x) {
    !is.nan(as.numeric(x)) & x != "Filtered" & !is.na(x)
}
set.seed(456)
data2 <- data.frame(
    ID = 1:6,
    Settings_X = c(1.1, 2.2, "Filtered", 4.4, NaN, 6.6),
    Settings_Y = c(1.1, 2.2, 3.3, NA, 5.5, "Filtered"),
    Settings_Z = c(1.1, 2.2, 3.3, 4.4, 5.5, 6.6),
    Info = LETTERS[1:6]
)

一行过滤多个列

res2 <- data2 %>%
    filter(if_all(contains("Settings"), is_valid))
 
print(res2)

🍁 3. 过滤“对照组/处理组全 NA”的行

在表达矩阵分析中,常常需要:

找出某组内全部为 NA 的行

例如 WT、KO 组:
封装成函数

find_na_rows <- function(group_name) {
    samples <- group_list[[group_name]] %>% pull(sample)
    which(rowSums(is.na(data[, samples, drop = FALSE])) == length(samples))
}

使用方式

WT_index <- find_na_rows("WT")
KO_index <- find_na_rows("KO")
 
WT_data <- data[WT_index, ]
KO_data <- data[KO_index, ]

🌿 4. 选择多列执行同一个函数

创建示例数据:

df <- data.frame(
    a = c(1.2, 2.3, 3.4, 4.5),
    b = c(5.6, 6.7, 7.8, 8.9),
    c = c("A", "B", "C", "D"),
    d = c(TRUE, FALSE, TRUE, FALSE),
    e = c(10, 20, 30, 40)
)

① 直接指定列名

df %>% mutate_at(vars(a, b), round)

② 使用列名向量

cols <- c("a", "b")
df %>% mutate_at(cols, ~ . * 2)

③ 使用选择器

df %>% mutate_at(vars(starts_with("a")), log)

🌈 5.、选择多列执行多个函数

如果你想同时对列 a、b:

  • 四舍五入(round)
  • 乘以 2

可以这样做:

df %>% mutate_at(
    vars(a, b),
    list(
        rounded = round,
        doubled = ~ . * 2
    )
)

输出类似:

aba_roundedb_roundeda_doubledb_doubled
1.25.6162.411.2

非常适用于数据预处理和表格扩展