如何在R语言中实现基于标准差筛选行的操作?
基于行标准差筛选数据行的实现方案
需求说明
筛选处于第一、第二、第三标准差范围内或之外的数据行,这里的标准差范围基于所有数据行的标准差统计值定义。
模拟数据集
先生成用于测试的模拟数据矩阵:
nr1 = 4; nr2 = 8; nr3 = 6; nr = nr1 + nr2 + nr3 nc1 = 6; nc2 = 8; nc3 = 10; nc = nc1 + nc2 + nc3 mat = cbind(rbind(matrix(rnorm(nr1*nc1, mean = 1, sd = 0.5), nr = nr1), matrix(rnorm(nr2*nc1, mean = 0, sd = 0.5), nr = nr2), matrix(rnorm(nr3*nc1, mean = 0, sd = 0.5), nr = nr3)), rbind(matrix(rnorm(nr1*nc2, mean = 0, sd = 0.5), nr = nr1), matrix(rnorm(nr2*nc2, mean = 1, sd = 0.5), nr = nr2), matrix(rnorm(nr3*nc2, mean = 0, sd = 0.5), nr = nr3)), rbind(matrix(rnorm(nr1*nc3, mean = 0.5, sd = 0.5), nr = nr1), matrix(rnorm(nr2*nc3, mean = 0.5, sd = 0.5), nr = nr2), matrix(rnorm(nr3*nc3, mean = 1, sd = 0.5), nr = nr3)) ) mat = mat[sample(nr, nr), sample(nc, nc)] # 随机打乱行和列 rownames(mat) = paste0("row", seq_len(nr)) colnames(mat) = paste0("column", seq_len(nc))
计算行标准差
原代码中m应为mat,修正后计算每行的标准差并存储:
library(tidyverse) rld2 <- as.data.frame(mat) %>% rownames_to_column('gene') bb <- rld2 %>% rowwise() %>% do(data.frame(., rsds = sd(unlist(.[2:length(.)]))))
筛选实现方案
步骤1:计算行标准差的全局统计量
先基于所有行的标准差,计算其均值和全局标准差,作为区间划分的基准:
mean_rsds <- mean(bb$rsds) sd_rsds <- sd(bb$rsds)
步骤2:按区间筛选数据
根据需求,可分别筛选处于不同标准差区间内或外的行:
第一标准差范围相关筛选
# 筛选处于第一标准差范围内的行(mean_rsds ± 1*sd_rsds) bb_first_in <- bb %>% filter(rsds >= mean_rsds - sd_rsds & rsds <= mean_rsds + sd_rsds) # 筛选处于第一标准差范围外的行 bb_first_out <- bb %>% filter(rsds < mean_rsds - sd_rsds | rsds > mean_rsds + sd_rsds)
第二标准差范围相关筛选
# 筛选处于第二标准差范围内的行(mean_rsds ± 2*sd_rsds) bb_second_in <- bb %>% filter(rsds >= mean_rsds - 2*sd_rsds & rsds <= mean_rsds + 2*sd_rsds) # 筛选处于第二标准差范围外的行 bb_second_out <- bb %>% filter(rsds < mean_rsds - 2*sd_rsds | rsds > mean_rsds + 2*sd_rsds)
第三标准差范围相关筛选
# 筛选处于第三标准差范围内的行(mean_rsds ± 3*sd_rsds) bb_third_in <- bb %>% filter(rsds >= mean_rsds - 3*sd_rsds & rsds <= mean_rsds + 3*sd_rsds) # 筛选处于第三标准差范围外的行 bb_third_out <- bb %>% filter(rsds < mean_rsds - 3*sd_rsds | rsds > mean_rsds + 3*sd_rsds)
补充:批量标记区间归属
如果需要给每行标记所属的区间类别,可使用case_when实现:
bb_with_label <- bb %>% mutate( sd_interval = case_when( rsds < mean_rsds - 3*sd_rsds | rsds > mean_rsds + 3*sd_rsds ~ "Outside 3σ", rsds < mean_rsds - 2*sd_rsds | rsds > mean_rsds + 2*sd_rsds ~ "Outside 2σ (Inside 3σ)", rsds < mean_rsds - sd_rsds | rsds > mean_rsds + sd_rsds ~ "Outside 1σ (Inside 2σ)", TRUE ~ "Inside 1σ" ) )
内容的提问来源于stack exchange,提问作者PesKchan
相关产品推荐
相关产品推荐

