2014-12-18 29 views
1

我试图读取包含节点数据(主要是p值)的.csv文件到我的程序中,但这样做我必须将它们从字符串转换为双精度。下面是它的方法:读取p值的.csv文件时,如何忽略/转换某些输入?

public ArrayList<Node> getCSVFile(String file){ 


     String csvFile = file; 
     BufferedReader br = null; 
     String line = ""; 
     String cvsSplitBy = ","; 
     ArrayList<Node> nL = new ArrayList<Node>(); 
     int count = 0; 

     try { 

      br = new BufferedReader(new FileReader(csvFile)); 
      while ((line = br.readLine()) != null) { 

        // use comma as separator 
       String[] node = line.split(cvsSplitBy); 


       double pVal = Double.parseDouble(node[4]); 
       nL.add(new Node(count, node[0], pVal)); 

       count++; 
      } 

     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (br != null) { 
       try { 
        br.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

    return nL; 
} 

目标节点是参数为节点(INT,字符串,双),但我想转换的文件的第一行是列名,和我不完全确定之后的条目的性质。下面就一起来看看该文件的开头:

基因,COMMON,gal1RGexp,gal4RGexp,gal80Rexp,gal1RGsig,gal4RGsig,gal80Rsig YHR051W,COX6,-0.034,0.111,-0.304,3.75720e-01,1.56240 e-02,7.91340e-06 YHR124W,NDT80,-0.090,0.007,-0.348,2.71460e-01,9.64330e-01,3.44760e-01 YKL181W,PRS1,-0.167,-0.233,0.112,6.27120e -03,7.89400e-04,1.44060e-01 YGR072W,UPF3,0.245,-0.471,0.787,4.10450e-04,7.51780e-04,1.37130e-05 YHL020C,OPI1,0.174,-0.015,0.151, 1.40160e-04,7.19120e-01,1.53950e-02 YGR145W,YGR145W,0.387,-0.577,-0.088,5.37920e-03,8.27330e-03,7.64180e-01 YGL041C,YGL041C,0.285,-0.086 ,0.103,4.46050e-04,4.50790e-01,7.03040e-0 1 YGR218W,CRM1,-0.018,-0.001,-0.018,6.13810e-01,9.79400e-01,8.09690e-01 YOR202W,HIS3,-0.432,-0.710,0.239,1.09790e-02,1.79790e- 04,5.48950e-03 YCR005C,CIT2,0.085,0.392,0.464,4.18980e-02,1.53050e-06,2.74360e-06 YER187W,KHS1,0.159,0.139,-0.045,8.51260e-04,4.17830e -0.3,6.18020e-01 YBR026C,YBR026C,0.276,0.189,0.291,3.63320e-05,6.15230e-04,1.24430e-03 YMR244W,YMR244W,0.078,-0.239,-0.072,5.76050e-01, 3.55240e-01,8.85690e-01 等等等等。

因此,代码为基于所述第一和第五列的每一行,以及独特的计数器创建节点。但是,我怎样才能跳过只有列名的第一行?我有点犹豫,只是略过所有文件中的所有第一行,因为并非所有读取的文件都可能有字符串作为第一行。即使如此,下面几行适合转换为双打?

谢谢!

回答

1

解析double时跳过行是不可能的? 像这样:

public ArrayList<Node> getCSVFile(String file){ 
    String csvFile = file; 
    BufferedReader br = null; 
    String line = ""; 
    String cvsSplitBy = ","; 
    ArrayList<Node> nL = new ArrayList<Node>(); 
    int count = 0; 

    try { 

     br = new BufferedReader(new FileReader(csvFile)); 
     while ((line = br.readLine()) != null) { 

       // use comma as separator 
      String[] node = line.split(cvsSplitBy); 
      double pVal; 

      try { 
       pVal = Double.parseDouble(node[4]); 
      } catch (NumberFormatException e) { 
       continue; // Skip this line if this isn't a double 
      } 

      nL.add(new Node(count, node[0], pVal)); 

      count++; 
     } 

    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } finally { 
     if (br != null) { 
      try { 
       br.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    return nL; 
} 
+0

与此相关的一个警告是,你失去了处理'实际'意外值的能力。一旦你通过第一行,任何错误的数据应该(可能)导致一个实际的错误 - 否则你可以成功读取一半的文件,而不会意识到另一半因为错误的字符而被跳过。这就是说我认为这个答案是在OP的要求下达成的。 – deyur 2014-12-19 02:34:38

+0

Deyur是正确的,这可能只是传递了一半的文件,但try/catch解决方案几乎与我所希望的一致(文件错误并不是真正的问题,因为我想用它来处理它)。谢谢! :D – Talex 2014-12-19 03:03:31

+0

好点@deyur。如果需要除了跳过非常规数据行(如标题)以外的任何行为,Talex可能希望用别的东西替代“continue;'的使用。 – ulix 2014-12-19 03:44:03

0

更改现有的方法来签名:

public ArrayList<Node> getCSVFile(String file, int startAt){ 

,并使用startAt你读的循环来控制多少行被跳过的内部。我建议创建一个返回所有行默认的方法:

public ArrayList<Node> getCSVFile(String file){ 
    return getCSVFile(file, 0); 
} 

或者这可能是一个布尔值,如果你知道,你要么要跳过第一行或根本没有。

至于你的问题的第二部分,许多这些字符串将不会被解析。您可能想要阅读this。但我不确定你希望如何解析或使用像'YHR051W'这样的值(因为你说你想要第一列)。

+0

欢呼声中,我实现了类似的东西了,但是否有可能写一些东西,会自动包括第一行,如果它可以转换的,如果它不能排除呢? – Talex 2014-12-19 02:19:36

+0

在这种情况下,ulix提供的解决方案可能是最好的选择。 – deyur 2014-12-19 02:31:49