如何 apply/loop 对 R 中的一组相似对象使用相同的函数

How to apply/loop the same function to a group of similar objects in R

我有一个大数据表,包含元数据,例如在不同条件下对样本进行不同药物处理以及测量的数字特征。

迷你虚拟数据集:

#I only used one sample here for simplicity. You can image there are multiple sample IDs
#and sometimes the same ID but different timestamp. 
#for each sample, the sample will have 3 levels conditions, 
#for each treatment(here's only 1, R), multiple dosages per condition
#on top of the condition&dose there is next layer to have combo or not.
#from id ~combo they are factors or at least I believe so
#after all these, the real measured variables V1,2.....

set.seed(123)
id <- rep("S112",30)  
timestamp <- rep("T4",30)
condit <- rep(c("uns","2S","3S"), 10)
treatment <- rep("R", 30)
dose <- rep(c("0.1","1"),each=15)
combo <-rep(c("none","I10","I100"),each=10)
v1 <-rnorm(30,0.5)
v2 <-rnorm(30,0.05)
v3 <-rnorm(30,0.1)
df <- data.frame(id,timestamp,condit,treatment,dose,combo,v1,v2,v3)

现在,如果我可以想象 R 的一种治疗,在不同的条件和不同的剂量甚至组合。

#import libs
library(ggplot2)
library(dplyr)
library(tidyr)
library(wesanderson)  #I have great movie taste I know

# now I look at treatment of interest
R <- df[df$treatment=="R" & df$combo == "I10",]

#table to long
R_long <- gather(R,7:9, key = bin, value = value, -id, -timestamp, -condit )
#plot it
b<- ggplot(R_long, aes(x=bin, y=id,fill=value))
pal <- wes_palette("Zissou1", 100, type = "continuous")
R_map <- b + 
  geom_tile()+
  scale_fill_gradientn(colors=pal)+
  facet_grid(dose~condit)+
  theme(text = element_text(size = 40,face="bold")) +
  theme(legend.text = element_text(size=35, face="bold"))+
  theme(axis.text.x = element_text(angle=45, hjust=1)) +
  theme(legend.key.size = unit(2, "cm"))+
  xlab("Bins")+
  ylab("Sample ID")+
  ggtitle("Plot of treatment R")

  ggsave(R_map,file="R.pdf",width=30,height=30) 

这行得通,但我想对真实数据集中的一组药物执行相同的操作,而不仅仅是一种治疗 R。我猜矢量化 R 语言应该允许像分组我想要的治疗在向量 c(R1, R2, R3, R4) 中并将上述代码应用于此向量。我怎样才能做到这一点?

注意:对于这个措辞糟糕的问题,我深表歉意。老实说,我对 R 的了解太基础了,甚至无法提出关键问题。所以请随时帮我编辑这个(COVID 部分是为了好精神)

谢谢

因为你已经 faceted,你不能往那个方向走,但如果你想要每个循环一个药物,然后将它包裹在一个 for 循环中:

for (tr in unique(df$treatment)) {
  R <- df[df$treatment==tr & df$combo == "I10",]
  R_long <- gather(R, 7:9, key = bin, value = value, -id, -timestamp, -condit)
  #plot it
  pal <- wes_palette("Zissou1", 100, type = "continuous")
  R_map <- ggplot(R_long, aes(x=bin, y=id, fill=value)) + 
    geom_tile() +
    scale_fill_gradientn(colors = pal) +
    facet_grid(dose ~ condit) +
    theme(text = element_text(size = 40, face="bold")) +
    theme(legend.text = element_text(size = 35, face = "bold")) +
    theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
    theme(legend.key.size = unit(2, "cm")) +
    xlab("Bins") +
    ylab("Sample ID") +
    ggtitle(paste("Plot of treatment", tr))
  ggsave(R_map, file = paste0(tr, ".pdf"), width = 30, height = 30) 
}

您还可以使用 mapmap2 来自 purrr

这里有一个 map2 的示例,它允许您从向量中添加另一个变量,例如组合:

library(purrr)

#get data
set.seed(123)
id <- rep("S112",30)  
timestamp <- rep("T4",30)
condit <- rep(c("uns","2S","3S"), 10)
treatment <- rep("R", 30)
dose <- rep(c("0.1","1"),each=15)
combo <-rep(c("none","I10","I100"),each=10)
v1 <-rnorm(30,0.5)
v2 <-rnorm(30,0.05)
v3 <-rnorm(30,0.1)
df <- data.frame(id,timestamp,condit,treatment,dose,combo,v1,v2,v3)


# make function if you use map, just remove y from the function and replace y with a variable within the function definition
makeplot <- function(x,y) {

# get data
R <- df[df$treatment==x & df$combo %in% unlist(strsplit(y, split="|", fixed=TRUE)),] #allows or statements in the vector
R_long <- gather(R, 7:9, key = bin, value = value, -id, -timestamp, -condit)
# make plot
pal <- wes_palette("Zissou1", 100, type = "continuous")
R_map <- ggplot(R_long, aes(x=bin, y=id, fill=value)) + 
  geom_tile() +
  scale_fill_gradientn(colors = pal) +
  facet_grid(dose ~ condit) +
  theme(text = element_text(size = 40, face="bold")) +
  theme(legend.text = element_text(size = 35, face = "bold")) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(legend.key.size = unit(2, "cm")) +
  xlab("Bins") +
  ylab("Sample ID") +
  ggtitle(paste("Plot of treatment", x))
ggsave(R_map, file = paste0(x,"_",paste0(gsub("|","_",y,fixed=TRUE)), ".pdf"), width = 30, height = 30) 
}

#make vectors, the function above allows you to combine combos with |
treatment <- c("R","R","R")
combo <- c("none","I10","none|I10")

#apply
map2(treatment,combo,makeplot)

PS:我希望您的研究将有助于为 COVID-19 患者找到有效的超适应症治疗。