• R语言
  • for循环里else if如何作用于2个或以上循环?

老师们,请教一个用R里for循环结合if来修改文本名的问题:
res_S的内容如下:
`
Classification
1 kBacteria|suncultured_bacterium_pAKD4
2 kBacteria|sbacterium_enrichment_culture_clone_2a(2010)
3 kBacteria|pCandidatus_Gracilibacteria|sCandidatus_Gracilibacteria_bacterium_HOT-871
4 k
Bacteria|pCoprothermobacterota
2724 k
Bacteria|pActinobacteria|cActinobacteria
2725 kBacteria|pActinobacteria|cActinobacteria|oCorynebacteriales
6423 kViruses|oCaudovirales|fMyoviridae|sProchlorococcus_phage_P-TIM68
6424 kViruses|oCaudovirales|fMyoviridae|gBusanvirus|sAcidovorax_virus_ACP17
6920 k
Viruses|oCaudovirales|fSiphoviridae|gTimquatrovirus|sMycobacterium_phage_Keshu
6921 kViruses|oCaudovirales|fSiphoviridae|gTimquatrovirus|sMycobacterium_phage_Omnicron
6922 k
Viruses|oCaudovirales|fSiphoviridae|gTimquatrovirus|sMycobacterium_phage_ZoeJ
6923 kViruses|oCaudovirales|fSiphoviridae|sVerrucomicrobia_phage_P8625
6924 kViruses|oCaudovirales|fSiphoviridae|sAchromobacter_phage_JWF
6925 kViruses|oCaudovirales|fSiphoviridae|sTsukamurella_phage_TPA4
6926 kViruses|oCaudovirales|fSiphoviridae|sSynechococcus_phage_S-CBS2
6927 kViruses|oCaudovirales|fSiphoviridae|sArchaeal_BJ1_virus
6928 kViruses|oCaudovirales|fSiphoviridae|sMycobacterium_phage_Sparky
6929 kViruses|oCaudovirales|fSiphoviridae|sRhodococcus_phage_REQ2
6930 kViruses|oCaudovirales|fSiphoviridae|sGordonia_phage_Phinally
6931 kViruses|oCaudovirales|fSiphoviridae|sCaulobacter_phage_CcrColossus
6932 kViruses|oCaudovirales|fSiphoviridae|sGordonia_phage_GTE8

`

判断red_S的第一列是否含我想要的内容:
library(dplyr)
library(stringr)
flt_sp <- as.data.frame(str_detect(res_S[,1],"p__"))
flt_sc <- as.data.frame(str_detect(res_S[,1],"c__"))
flt_so <- as.data.frame(str_detect(res_S[,1],"o__"))
flt_sf <- as.data.frame(str_detect(res_S[,1],"f__"))
flt_sg <- as.data.frame(str_detect(res_S[,1],"g__"))

根据上述判断条件来增加res_S的内容:
for (i in 1:nrow(res_S)) {
if(flt_sp[i,1]=="FALSE"&&flt_sc[i,1]=="FALSE"&&flt_so[i,1]=="FALSE"&&flt_sf[i,1]=="FALSE"&&flt_sg[i,1]=="FALSE"){
sgs <- res_S[i,1]
res_S[i,1]=gsub("s__","1__22|a__155|b__n5e|g__uu6", sgs)##这里没问题
}else if(flt_sp[i,1]=="FALSE"&&flt_sc[i,1]=="FALSE"&&flt_so[i,1]=="TRUE"&&flt_sf[i,1]=="TRUE"&&flt_sg[i,1]=="FALSE"){
sgs <- res_S[i,1]
res_S[i,1]=gsub("o__","p__op|y__noname666|o__", sgs)###疑问1
res_S[i,1]=gsub("s__","gofw123t__noname|s__" ,sgs)###疑问2
}else {
res_S[i,1]=res_S[i,1]
}
}

结果发现,“###疑问2”更改了res_S对应的内容,但“###疑问1”这里没有起到作用,我把“###疑问2"这行代码删掉,然后“###疑问1”是可以更改res_S对应的内容,对比“###疑问0”,下面的“###疑问1”和“###疑问2”多了一行循环内容,我目前想到的办法是先执行“###疑问1”,然后再写另一个for循环执行“###疑问2”,我感觉这样很笨并且啰嗦,还请老师们给出个招,谢谢。

自我回答一下,将
`res_S[i,1]=gsub("o","pop|ynoname666|o", sgs)###疑问1

res_S[i,1]=gsub("s","gofw123tnoname|s__" ,sgs)###疑问2
`

改为
`
aa=gsub("o","pop|ynoname666|o", sgs)###疑问1

res_S[i,1]=gsub("s","gofw123tnoname|s__" ,aa)###疑问2
`

henrywangnl 抱歉,我刚刚疏忽了发帖规则,我的工作内容如下:我想要数据表第一列结构为:

k__aaa|p__sss|c__ddd|o__fppps|f__hbvbduvb|g__ssbcjb|s__dividvid

我们可以看到上面的内容是以“|”隔开,从k到s为7个级别,如上的内容是我想要的,但是,第一列有些行只为kaaa|sdddbjsvbbv,中间就少了psss|cddd|ofppps|fhbvbduvb|gssbcj等内容,因此我想判断第一列是否含有p或其他内容,若结果为FALSE,那么则根据c是否存在,若存在,则修改这一列这一行的内容为kaaa|pnoname|c已经存在的内容。总体上是这样,这是处理微生物数据格式的需求。我上面贴的代码,基本上是完整的。res_S的内容:

	class_sp	st1	st2	st3	st4	st5	st6	st7	st8	st9
1	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Verrucomicrobia_phage_P8625	1	0	0	0	1	0	0	0	0
2	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Achromobacter_phage_JWF	1	0	0	1	2	0	0	0	1
3	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Tsukamurella_phage_TPA4	1	0	0	1	0	0	1	1	0
4	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Synechococcus_phage_S-CBS2	1	0	1	0	0	0	0	0	0
5	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Archaeal_BJ1_virus	1	0	0	0	0	0	0	0	0
6	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Mycobacterium_phage_Sparky	1	4	2	0	0	1	0	0	0
7	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Rhodococcus_phage_REQ2	1	0	1	0	0	0	0	1	0
8	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Gordonia_phage_Phinally	1	0	0	0	0	0	0	0	0
9	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Caulobacter_phage_CcrColossus	2	1	2	3	1	2	1	2	2
10	k__Viruses|o__Caudovirales|f__Siphoviridae|s__Gordonia_phage_GTE8	2	2	0	2	0	0	0	1	0

```  

    wqssf

    大概明白了,你想做的是补其界门纲目科属种的信息对吧。但“则修改这一列这一行的内容为kaaa|pnoname|c已经存在的内容”感觉很容易出错,假如不同phylum下有两个class名字一样,那根据class来补齐上两级的kindom, phylum就会出错(也可能我多虑了)

    个人建议是用公有数据库(NCBI)来补齐这些信息,比如下面这个R包就能根据species来查找上层分类信息。

    https://cran.r-project.org/web/packages/myTAI/vignettes/Taxonomy.html

      tctcab 谢谢,看来是遇到大佬了,我是用kraken2注释宏基因组测序,预先处理了结果,再用上述代码来补全分类水平,目前没发觉您说的情况,非常感谢您推荐的这个包,我试试。

        3 个月 后

        wqssf 自我回复一下,后期改变了策略,直接列举每一行物种了。用正则的模糊匹配会出问题。比如一个物种是以s结尾,那么它会连接下划线,那么这个和种水平的s就会被认为是一样!