R将用户定义的函数应用于列的每一行

R applying a user-defined function to each row of a column

我有一个包含 uniprot 加入和 ID 的数据框,如下所示:

> a <- data.frame(protein=c("sp|A6NCE7|MP3B2_HUMAN,sp|Q9GZQ8|MLP3B_HUMAN","sp|A6NL28|TPM3L_HUMAN","sp|B5ME19|EIFCL_HUMAN,sp|Q99613|EIF3C_HUMAN"),stringsAsFactors=FALSE)
> a
                                      protein
1 sp|A6NCE7|MP3B2_HUMAN,sp|Q9GZQ8|MLP3B_HUMAN
2                       sp|A6NL28|TPM3L_HUMAN
3 sp|B5ME19|EIFCL_HUMAN,sp|Q99613|EIF3C_HUMAN

现在,我编写了一个将每个字符串拆分为可用部分的函数:

split.uniprot.string <- function(uniprot_string){
  first.protein <- unlist(strsplit(uniprot_string,"[,]"))[1]
  uniprot_accession <- unlist(strsplit(first.protein,"[|]"))[2]
  uniprot_ID <- unlist(strsplit(first.protein,"[|]"))[3]
  list(uniprot_ID=uniprot_ID, uniprot_accession=uniprot_accession)
}

如果我将它应用于单行,效果很好:

> split.uniprot.string(a$protein[2])
$uniprot_ID
[1] "TPM3L_HUMAN"

$uniprot_accession
[1] "A6NL28"

但是,如果我尝试将它应用于数据帧的每一行,该函数以某种方式仅正确应用于第一行(如果我 运行 每行上的 FOR 循环,也会发生同样的情况):

> a$uniprot_ID <- apply(a,1,function(row) split.uniprot.string(a$protein)$uniprot_ID)
> a
                                      protein  uniprot_ID
1 sp|A6NCE7|MP3B2_HUMAN,sp|Q9GZQ8|MLP3B_HUMAN MP3B2_HUMAN
2                       sp|A6NL28|TPM3L_HUMAN MP3B2_HUMAN
3 sp|B5ME19|EIFCL_HUMAN,sp|Q99613|EIF3C_HUMAN MP3B2_HUMAN

我必须更改什么,以便函数在每一行中填写正确的 uniprot_ID(即第 2 行中的 "TPM3L_HUMAN" 和第 3 行中的 "EIF3C_HUMAN")?

我觉得你的问题有点复杂(除了"typo")。

据我了解,您对第一个"sequence"的最后部分感兴趣,最后|之后的那个|?

如果是这样,你可以这样做:

a$uniprot_ID <- gsub("^sp\|{1}[^|]+\|{1}([^|,]+)($|,.*)","\1",a$protein)

a
#                                      protein  uniprot_ID
#1 sp|A6NCE7|MP3B2_HUMAN,sp|Q9GZQ8|MLP3B_HUMAN MP3B2_HUMAN
#2                       sp|A6NL28|TPM3L_HUMAN TPM3L_HUMAN
#3 sp|B5ME19|EIFCL_HUMAN,sp|Q99613|EIF3C_HUMAN EIFCL_HUMAN

如果你还想要第一个 "sequence" 的第一个 | 之后的部分(如果是逗号),你可以这样做:

a$uniprot_accession <- gsub("^sp\|{1}([^|]+).*","\1",a$protein)

a
#                                      protein  uniprot_ID uniprot_accession
#1 sp|A6NCE7|MP3B2_HUMAN,sp|Q9GZQ8|MLP3B_HUMAN MP3B2_HUMAN            A6NCE7
#2                       sp|A6NL28|TPM3L_HUMAN TPM3L_HUMAN            A6NL28
#3 sp|B5ME19|EIFCL_HUMAN,sp|Q99613|EIF3C_HUMAN EIFCL_HUMAN            B5ME19