背景:我正在研究基因和本体,但我的问题是关于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(gene_list_and_Go_ID,1,unlist(strsplit(gene_list_and_Go_ID[,2], split=", ")))
我得到了:
Error in strsplit(ok, split = ", ") : non-character argument
2 /然后,我可以将请求添加到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
感谢您的帮助。
答案 0 :(得分:2)
最近的问题是你不像你那样打电话给apply
。你没有像你那样编写一个函数调用,而是需要提供一个函数,它将数组的每一行/列依次作为输入通过它的第一个参数,所以你需要类似的东西(未经过测试) ,因为你不需要这个)
apply(gene_list_and_Go_ID, 1,
function(x) { unlist(strsplit(x[2], split=", "))})
但请注意,您不需要gene_list_and_Go_ID
的完整行。您想要的是处理V2
的{{1}} 列。现在还要注意gene_list_and_Go_ID
vectorised ,这意味着如果你传递一个长度大于1的向量,它将对该向量的每个元素起作用,就像你反复调用{{依次对矢量的每个元素进行1}}。
请考虑以下事项:
strsplit
请注意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
- &gt; stringsAsFactors = FALSE
,但您也可以在下面的代码中使用character
factor
。
要在as.character(V2)
的每个元素上运行V2
,我们可以使用:
strsplit
让我们
V2
通过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)
的结果。
将它重新组合在一起你可能想要:
select
但我无法测试最后几个部分,因为我不知道df
来自哪里,创造了什么out <- cbind.data.frame(Gene = rep(names(spl), each = lengths(spl)),
do.call("rbind", term))
答案 1 :(得分:0)
好的,根据Gavin的回答和他的帮助,我得到了正确的剧本。但是有一个非常重要的步骤阻止了我:将我的“gene_list_and_Go_ID”数据框第二列从因子转换为字符。我这样做是为了跳过“strsplit”函数中的“非字符参数”错误。这篇文章帮助了我:LINK
所以这是我的起始数据框:
unless Rails.env == 'production'
接下来是脚本。 第一个新行似乎非常有用(将我的df从因子转换为字符):
>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
下:
>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)
注意,我跳过了最后一个Gavin的建议:
> 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 ...
这可能是一个非常优雅的剧本,但我很难理解它的作用,以及它产生的内容:
out <- cbind.data.frame(Gene = rep(names(spl), each = lengths(spl)),
do.call("rbind", term))
THX