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
我有一个包含 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