如何加速一个简单的R代码绘制箱线图

在进行人工智能大模型的答疑的时候,演示了一个简单的表达量芯片数据集:GSE66175,但是它的样品数量确实是有点多,所以一个简单的R代码绘制箱线图都耗时很久,如下所示:

```r
library(AnnoProbe)
library(GEOquery)
gse_number <- ‘GSE66175’
if(T){gset <- geoChina(gse_number)}
a=gset[[1]]
dat=exprs(a)

~~~查看数据是否需要log~~~

boxplot(dat[,1:4],las=2)
range(dat)
boxplot(dat,las=2)


是时候做一个简单的加速啦:

### 有多种方法可以用来测量函数或代码块的执行时间

1. **使用 `Sys.time()` 函数**:通过记录代码执行前后的时间戳,然后相减得到执行时间。这种方法简单直接,适用于大多数情况。例如:
 ```r
 start_time <- Sys.time()
 # 执行你的代码
 end_time <- Sys.time()
 print(end_time - start_time) # 输出执行时间
  1. 使用 system.time() 函数:这个函数可以直接返回一个包含用户时间、系统时间和经过时间的列表,用于测量代码块的执行时间。例如:

    system.time({
    # 执行你的代码
    })
    
  2. 使用 microbenchmark

  3. 使用 rbenchmark

  4. 使用 tictoc:这个包提供了 tic()toc() 函数,用于测量代码块的执行时间

  5. 使用 proc.time() 函数

看看如何改进这20秒

这个箱线图之所以好费时间,其实是因为样品数量实在是太多了:

start_time <- Sys.time()
# 执行你的代码
boxplot(dat,las=2)
end_time <- Sys.time()
print(end_time - start_time) # 输出执行时间
 # 输出执行时间 Time difference of 20.27155 secs

可以看到这个表达量矩阵蛮奇怪的:前面的部分样品和后面的表达量范围完全不一样:

前面的部分样品和后面的表达量范围完全不一样

我问了人工智能大模型:r编程语言里面的更快地绘制boxplot呢

在R语言中,绘制箱线图(Boxplot)是一种常用的数据可视化方法,它可以展示数据的分布特征,包括中位数、四分位数以及异常值等。以下是几种快速绘制箱线图的方法:

  1. 使用基础图形系统中的 boxplot() 函数

    • 您可以使用基础R的 boxplot() 函数来创建箱线图。例如,使用 boxplot() 函数并传入一个公式,可以对数据进行分组并绘制箱线图。boxplot(len ~ dose, data = ToothGrowth) 这样的代码可以创建一个按剂量分组的牙齿长度箱线图 。
  2. 使用 ggplot2

    • ggplot2 是R语言中一个非常强大的绘图包,它提供了 geom_boxplot() 函数来绘制箱线图。您可以通过 aes() 函数设置美学映射,并通过 geom_boxplot() 来添加箱线图图层。例如,ggplot(ToothGrowth, aes(x = dose, y = len)) + geom_boxplot() 可以创建一个根据剂量分组的牙齿长度的箱线图 。
  3. 使用 boxplot.stats() 函数

    • 在绘制箱线图之前,boxplot.stats() 函数可以帮助您计算箱线图的统计量,包括中位数、四分位数和异常值。这对于自定义箱线图的某些方面可能很有用 。
  4. 调整箱线图的样式

    • 您可以使用 col 参数为箱线图设置颜色,使用 notch 参数来决定是否绘制带凹口的箱线图,以及使用 varwidth 参数来使箱线图的宽度与样本量的平方根成正比 。
  5. 使用 facet_grid() 创建分面箱线图:

    • 当您想要根据多个分类变量来展示数据分布时,可以使用 facet_grid() 函数来创建分面箱线图。例如,ggplot(diamonds, aes(x = color, y = price)) + geom_boxplot() + facet_grid(cut ~ clarity) 可以创建一个按切割质量和清晰度分面的钻石价格箱线图 。
  6. 使用 vioplot 包绘制小提琴图

    • 虽然不是箱线图,小提琴图结合了箱线图和核密度图的特点,可以提供更多关于数据分布的信息。vioplot() 函数可以用来绘制小提琴图,它需要分组变量和数值变量 。

每种方法都有其特点和适用场景,您可以根据自己的需求选择合适的方法来快速绘制箱线图。

我测试了ggplot体系的绘图,但是节省的时间很有限,虽然是宽数据变成长数据是OK的 :

start_time <- Sys.time()
df=melt(dat)
head(df)
library(ggpubr)
ggboxplot(df, x="Var2", y="value", fill="Var2") +
 theme(legend.position = "none") # 不显示图例
end_time <- Sys.time()
print(end_time - start_time) # 输出执行时间
# Time difference of 16.41384 secs

上面的boxplot.stats() 函数可以做的快速对每个样品进行箱线图统计:

data=dat[,1]
stats <- boxplot.stats(data)
boxplot(stats$stats, names=stats$names, 
 main="Boxplot Stats Visualization", ylab="Variable")

start_time <- Sys.time()
df=apply(dat, 2,function(x) boxplot.stats(x)$stats)
boxplot(df)
end_time <- Sys.time()
print(end_time - start_time) # 输出执行时间
# Time difference of 1.737396 secs

确实是快了很多哦!但是我其实是应该是另外一种可视化,因为直接使用boxplot函数可视化 boxplot.stats函数对一个向量的统计学结果,并不等价于boxplot函数可视化那个向量本身,如下所示:

并不等价于boxplot函数可视化那个向量本身

但是人工智能代码给我的回答并不是这样的:使用 boxplot.stats 函数得到的统计结果与直接使用 boxplot 函数绘制原始数据向量的箱线图在概念上有所不同,但它们可以提供相似的视觉效果和统计信息。下面是两者的区别和联系:

  1. boxplot 函数

    • 直接对数据向量进行可视化,生成箱线图。
    • 箱线图展示了数据的最小值、第一四分位数(Q1)、中位数、第三四分位数(Q3)和最大值。
    • 还可以识别和显示异常值(outliers)。
  2. boxplot.stats 函数

    • 计算数据向量的一些统计量,但不直接绘图。
    • 返回的是一个包含中位数、四分位数、四分位距、异常值等统计信息的列表。
    • 可以使用这些统计量来手动绘制箱线图或进行其他统计分析。

如果你使用 boxplot 函数直接对数据向量进行绘图,R 会自动计算所需的统计量并绘制箱线图。而当你使用 boxplot.stats 函数时,你得到了这些统计量的数据,可以对它们进行进一步的分析或绘图。

如果你想要使用 boxplot.stats 的结果来可视化,你可以手动将这些统计量绘制成箱线图,或者使用 boxplot 函数的参数来指定这些统计量。以下是使用 boxplot.stats 结果进行可视化的示例代码:

# 假设有一个数据向量
data_vector <- c(1:100, 1000)

# 使用 boxplot.stats 计算统计量
stats_result <- boxplot.stats(data_vector)

# 使用 base R 的 boxplot 函数和 stats_result 绘制箱线图
boxplot(data_vector, 
 stats = stats_result$stats, # 使用 boxplot.stats 的结果
 names = stats_result$names, # 如果有分组,使用分组名称
 ylab = "Value", 
 main = "Boxplot using stats from boxplot.stats")

在这个示例中,我们首先使用 boxplot.stats 计算了数据向量的统计量,然后使用这些统计量作为 boxplot 函数的参数来绘制箱线图。这样,boxplot 函数的可视化效果是基于 boxplot.stats 的统计结果,两者在视觉呈现上是一致的,但方法上有所区别。

Comments are closed.