上下文:我正在处理基因和本体,但我的问题与R脚本编写有关。
我想用从数据库中提取的相应术语替换我的数据框中的GO:ID。
所以,这是我的源数据框。它是一个基因列表(v1)和相关的GO:ID (v2):
>gene_list_and_Go_ID
V1 V2
2563 Gene1 GO:0003871, GO:0008270, GO:0008652, GO:0009086
2580 Gene2 GO:0003871, GO:0008270, GO:0008652, GO:0009086
12686 Gene3 GO:0003871, GO:0008270, GO:0008652, GO:0009086
14523 Gene4 GO:0004489, GO:0006555, GO:0055114对数据库的请求看起来非常简单:
>select(GO.db, my_Go_id, "TERM", "GOID")我尝试了以下几行代码来手动访问数据库,它工作得很好:
>my_Go_id = unlist(strsplit("GO:0008270, GO:0008652, GO:0009086", split=", "))
>select(GO.db, my_Go_id, "TERM", "GOID")
GOID TERM
1 GO:0008270 zinc ion binding
2 GO:0008652 cellular amino acid biosynthetic process
3 GO:0009086 methionine biosynthetic process我的问题是:我不能让这个过程自动化!准确地说,对于每一行,我需要将数据框中第n°2列的每个字符串转换为一个向量,以便查询数据库。然后我需要用请求的结果替换数据框中的GO:ID。
1/首先,我尝试将"unlist“函数放在"apply”函数中,以应用到我的数据框中:
apply(gene_list_and_Go_ID,1,unlist(strsplit(gene_list_and_Go_ID[,2], split=", ")))我得到了:
Error in strsplit(ok, split = ", ") : non-character argument2/然后,我可以将请求也添加到apply函数内的数据库中吗?
3/最后,我不知道如何将n°2列替换为数据库请求的结果。
这是一个例外的“理想”结果的示例:
V1 V2
2563 Gene1 GOID TERM
1 GO:0008270 zinc ion binding
2 GO:0008652 cellular amino acid biosynthetic process
3 GO:0009086 methionine biosynthetic process谢谢你的帮助。
发布于 2016-07-19 23:07:34
最直接的问题是,您没有像以前那样调用apply。与您编写函数调用不同,您需要提供一个函数,该函数将通过其第一个参数依次获取数组的每一行/每一列作为输入,因此您需要类似于(未测试,因为您不需要它)的内容。
apply(gene_list_and_Go_ID, 1,
function(x) { unlist(strsplit(x[2], split=", "))})但是,请注意,您不需要整行的gene_list_and_Go_ID。您想要的是处理gene_list_and_Go_ID的V2列。现在还要注意,strsplit是矢量化的,这意味着如果你向它传递一个长度大于1的向量,它将对该向量的每个元素起作用,就像你依次对该向量的每个元素重复调用strsplit()一样。
请考虑以下几点:
df <- data.frame(V1 = paste0("Gene", 1:4),
V2 = c("GO:0003871, GO:0008270, GO:0008652, GO:0009086",
"GO:0003871, GO:0008270, GO:0008652, GO:0009086",
"GO:0003871, GO:0008270, GO:0008652, GO:0009086",
"GO:0004489, GO:0006555, GO:0055114"),
stringsAsFactors = FALSE)请注意,V2需要是一个字符向量-这里我使用stringsAsFactors = FALSE来停止自动强制character -> factor,但您也可以在下面的代码中使用as.character(V2),其中我有V2。
要在V2的每个元素上运行strsplit,我们可以使用:
spl <- with(df, strsplit(V2, ", "))这让我们
> spl
[[1]]
[1] "GO:0003871" "GO:0008270" "GO:0008652" "GO:0009086"
[[2]]
[1] "GO:0003871" "GO:0008270" "GO:0008652" "GO:0009086"
[[3]]
[1] "GO:0003871" "GO:0008270" "GO:0008652" "GO:0009086"
[[4]]
[1] "GO:0004489" "GO:0006555" "GO:0055114"从select调用的外观来看,这是一次成功的交易-您需要为df (您的gene_list_and_Go_ID)中的所有行调用它。如果是这样,只需迭代strsplit()返回的列表元素
names(spl) <- with(df, as.character(V1))
term <- lapply(spl, function(x, db) select(db, x, "TERM", "GOID"),
db = GO.db)这将返回一个列表,其中每个元素都是针对df的单个基因/行调用select的结果。
把它放回原处,你可能需要:
out <- cbind.data.frame(Gene = rep(names(spl), each = lengths(spl)),
do.call("rbind", term))但是我不能测试最后几个部分,因为我不知道select()是从哪里来的,也不知道是什么创造了GO.db
发布于 2016-07-20 17:17:16
好的,根据Gavin的回答和他的帮助,我得到了正确的脚本。但是有一个非常重要的步骤阻碍了我:将我的"gene_list_and_Go_ID“数据框第二列从因子转换为字符。我这样做是为了跳过"strsplit“函数中的”非字符参数“错误。这篇文章帮助了我:LINK
所以这是我的起始数据框:
>gene_list_and_Go_ID
V1 V2
2563 Gene1 GO:0003871, GO:0008270, GO:0008652, GO:0009086
2580 Gene2 GO:0003871, GO:0008270, GO:0008652, GO:0009086
12686 Gene3 GO:0003871, GO:0008270, GO:0008652, GO:0009086
14523 Gene4 GO:0004489, GO:0006555, GO:0055114接下来是脚本。第一个新行看起来非常有用(将我的df从因子转换为字符):
>gene_list_and_Go_ID <- data.frame(lapply(gene_list_and_Go_ID, as.character), stringsAsFactors=FALSE)接下来:
>V_ID <- with(gene_list_and_Go_ID, strsplit(V2, ", "))
>names(V_ID) <- with(gene_list_and_Go_ID, as.character(V1))
>terms <- lapply(V_ID, function(x, db) select(db, x, "TERM", "GOID"), db = GO.db)最终输出是完美的:-):
> terms
$Gene1
GOID TERM
1 GO:0003871 S-methyltransferase activity
2 GO:0008270 zinc ion binding
3 GO:0008652 cellular amino acid biosynthetic process
4 GO:0009086 methionine biosynthetic process
$Gene2
... etc ...
... etc ...注意,我跳过了最后一个Gavin的建议:
out <- cbind.data.frame(Gene = rep(names(spl), each = lengths(spl)),
do.call("rbind", term))这可能是一个非常优雅的脚本,但我很难理解它的所有功能,下面是它生成的内容:
Error in data.frame(..., check.names = FALSE) :
arguments imply differing number of rows: 16, 15
In addition: Warning message:
In rep(names(V_ID), each = lengths(V_ID)) :
first element used of 'each' argumentTHX
https://stackoverflow.com/questions/38461731
复制相似问题