我们拿到的数据有时可能是这样的
而我们希望,所有的数据都应该是这样(以上图中CHEMBL474208为例):
解决方案:
#分解复合元素,并扩展原始数据
library(data.table)
dtc <- fread("C:/Users/10530/Desktop/DTc/DtcDrugTargetInteractions.csv", sep = ",", stringsAsFactors = F, na.strings = "", data.table = T)#导入原始数据
dtc_small <- dtc[,c("compound_id", "target_id", "standard_type", "standard_value", "standard_units")]#去除不需要的列
dtc_small <- na.omit(dtc_small)#去除有缺失值的行
#judge函数:对需要分解的行进行标注
judge <- function(line_t){
if(nchar(line_t[2])>6){ #nchar计算字符串长度
return(1) #label = 1 为需要分解的行
}
else{
return(0)#label = 0 为不需要分解的行
}
}
label <- apply(dtc_small, 1, judge)
dtc_small$label <- label #打上标记
dtc_small_keep <- dtc_small[which(dtc_small$label==0), ] #保持不不要修改的部分
dtc_small_modify <- dtc_small[which(dtc_small$label==1), ] #需要修改的部分
#分解函数,按行分解
decompose <- function(row){
row <- as.character(row)
tmp <- unlist(strsplit(row[2], ","))#将复合target分解
l_t <- length(tmp) #计算分解出的target个数
drug_t <- rep(row[1], l_t) #其他项直接自我复制
sta_type <- rep(row[3], l_t)
sta_value <- rep(row[4], l_t)
sta_units <- rep(row[5], l_t)
df_tmp <- data.frame(compound_id=drug_t,
target_id=tmp,
standard_type=sta_type,
standard_value=sta_value,
standard_units=sta_units)#分解后,扩展成新的数据框
return(df_tmp)
}
#对目标数据进行处理,采用并行法进行加速
library(parallel) #并行处理包
cl.cores <- detectCores(logical = F) #计算电脑核心数
cl <- makeCluster(cl.cores) # 初始化要使用的核心数
results <- parApply(cl=cl, dtc_small_modify, 1, decompose) # apply的并行版本
library(dplyr)
res.df <- bind_rows(results)#整合所生成的所有数据框,合成一个数据框,这里会产生警告,不影响结果
dtc_small_keep <- dtc_small_keep[, -6] #去掉label项
fin.df <- rbind(res.df, dtc_small_keep) #将不需要扩展的和已经扩展好的数据框,合成最终结果
#去除字符串中前后多余空格
library(stringr)
fin.df$target_id <- str_trim(fin.df$target_id,'both') #去除字符串前后多余空格,防止对后面的检查造成误判
#再次检查一下,是否存在需要分解的行
label <- apply(fin.df, 1, judge)
fin.df$label <- label #打好标记
sum(fin.df$fin.df$label == 1) #检查一下,是否存在需要分解的行
write.csv(fin.df, file = "fin.df.csv", col.names = F)#导出数据
Tips:关于上述代码一些补充资料
bind_rows函数:垂直合并多个数据框为一个数据框 parallel并行处理包在向量化操作中的应用
END
|
请发表评论