缘由
生信之路,道阻且长,记录经验,但渡有缘人。
碎碎念
及时当勉励,岁月不饶人 ——陶渊明
代码
在日常的数据分析中,我们经常会遇到以下需求:
- 判断 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 / 特殊值并过滤
实际数据中常出现:
NANaN"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
)
)输出类似:
| a | b | a_rounded | b_rounded | a_doubled | b_doubled |
|---|---|---|---|---|---|
| 1.2 | 5.6 | 1 | 6 | 2.4 | 11.2 |
非常适用于数据预处理和表格扩展