如果.. else如果.. else在R中循环

时间:2018-10-18 15:18:33

标签: r loops subset

我尝试使用R中一个较长的循环,以便根据它们在特定列中的值来对齐两个数据帧(dosageldpred)。对于即将到来的文字墙,我会先表示歉意,但这感觉很复杂(可能有一个非常简单的解决方案)。

该循环应该从snp中获取字符串ldpred的值,并在dosage中找到相同的字符串,然后从dosage中提供特定的行。然后,应该使用ldpred中其他两个列的值,并将它们与dosage中的相应列进行比较。如果值匹配,则应该在新列中将其淘汰1。如果它们匹配但在相反的列中,则应该输出-1。没关系。

但是,棘手的部分是它还应该将ldpred的值切换为不同的值,然后重复上述相同的检查。

如果所有这些都不返回1或-1(即,由于某种原因这些值根本不匹配),则应该返回0。

根据要求进行编辑,其中包含我的数据和输出示例:

剂量:

chr snp a1 a2 p-value
1 rs1234 A G 0.05
2 rs2345 C T 0.03
3 rs5555 G T 0.001
4 rs9876 C G 0.02

LDpred:

chr sid nt1 nt2 beta OUTPUT
1 rs1234 A G 0.001 1
2 rs2345 T C 0.002 -1
3 rs5555 C A 0.003 1
4 rs9876 CC GG 0.004 0

希望这会使它更加清晰。我试图在LDpred中找到SNP的值,在剂量中找到相应的SNP值,然后将nt1与a1和nt2与a2进行比较。 /编辑

这是脚本:

for (line in 1:nrow(ldpred)){

  # Input rsID and genotype of specific line of LDpred file

  snp_ld = ldpred$sid[line]
  ref_ld = ldpred$nt1[line]
  alt_ld = ldpred$nt2[line]

  # Obtain opposing line from dosage file using rsID

  genotype = subset(dosage, snp == snp_ld)

  # Extract dosage file genotypes from dosage line

  ref_gen = genotype$a1
  alt_gen = genotype$a2

  if (ref_ld == ref_gen && alt_ld == alt_gen){

    # If alleles in both files match, return 1

    ldpred$matched[line] = 1

    }  else if (ref_ld == alt_gen && alt_ld == ref_gen){

      # If alleles in both files are exact opposites, return -1

      ldpred$matched[line] = -1

      }  else{

        # Make sure that files aren't using alternate strands
        # Switch alleles to opposing strand using switch_strand function

        ref_ld_switched = switch_strand(ref_ld)
        alt_ld_switched = switch_strand(alt_ld)

        if (ref_ld_switched == ref_gen && alt_ld_switched == alt_gen){

          # If new switched alleles match, return 1

          ldpred$matched[line] = 1

          }  else if (ref_ld == alt_gen && alt_ld == ref_gen){

            # If new switched alleles are opposites, return -1 

            ldpred$matched[line] = -1

          }  else {

            # If the alleles do not match then return 0 for QC

            ldpred$matched = 0

          }
      }
}

最初,我使用for .. if .. else循环和相应的花括号有很多问题,但是我认为我已经对它进行了排序(但是,如果有人发现任何错误,我会d感谢您被告知)。现在,尽管我得到了错误

Error in if (ref_ld == ref_gen && alt_ld == alt_gen) { :   
  missing value where TRUE/FALSE needed

我认为最初的for步骤中可能发生了错误,但是我确信它可以正确地从相应文件中提取所有内容。可能是因为其中一个文件比另一个大,所以当它停止能够针对两个文件检查值时,会导致脚本失败吗?

任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:0)

在事后看来,我认为这是一个错误的论坛,要提出这样一个特定的问题,它本质上与调试有关。

后代:我已经确定了我自己的问题的答案,实际上是因为数据文件的大小不同。因此,最终genotype变量最终成为空值,当将其输入到if循环的第一阶段时,它随后输出“缺少值”错误。

答案 1 :(得分:0)

R非常适合矢量操作,并允许使用方括号轻松索引数据。最好利用这一点,并尽可能避免使用循环。这是您的代码的替代方法:

dosage <- read.table(text =
  'chr snp a1 a2 p-value
  1 rs1234 A G 0.05
  2 rs2345 C T 0.03
  3 rs5555 G T 0.001
  4 rs9876 C G 0.02',
  header = TRUE, stringsAsFactors = FALSE)

ldpred <- read.table(text =
  'chr sid nt1 nt2 beta
  1 rs1234 A G 0.001
  2 rs2345 T C 0.002
  3 rs5555 C A 0.003',
  header = TRUE, stringsAsFactors = FALSE)
# I removed the last line to show what happens when you have different sizes

mergedData <- merge(ldpred, dosage, by.x = c('chr','sid'), by.y = c('chr','snp'), all = TRUE)

mergedData$OUTPUT <- 0
mergedData$OUTPUT[mergedData$nt1 == mergedData$a1 & mergedData$nt2 == mergedData$a2] <- 1
mergedData$OUTPUT[mergedData$nt1 == mergedData$a2 & mergedData$nt2 == mergedData$a1] <- -1
mergedData$OUTPUT[apply(mergedData[,c('nt1','nt2','a1','a2')], 1, anyNA)] <- NA

> mergedData
  chr    sid  nt1  nt2  beta a1 a2 p.value OUTPUT
1   1 rs1234    A    G 0.001  A  G   0.050      1
2   2 rs2345    T    C 0.002  C  T   0.030     -1
3   3 rs5555    C    A 0.003  G  T   0.001      0
4   4 rs9876 <NA> <NA>    NA  C  G   0.020     NA

merge()保证您的数据对齐以执行矢量比较,您可以通过其他方式做到这一点。您也可以删除选项all = TRUE,这样您只有匹配的行,避免了NA。我通常不这样做,因为NA是一种信息。