在SAS或R中读取原始数据

时间:2012-08-25 15:02:59

标签: r sas

对于我们的分析,我们需要从csv(xls)&读取原始数据。在进行分析之前将其转换为SAS数据集。

现在,问题是这个原始数据通常有两个问题:    1.列的排序有时会发生变化。所以,如果在前一个时期我们按照变量A的顺序排列,那么B,然后是C,等等。它可能会变为B,然后是C,然后是A.    2.有“#”,“。”,或“某些字母”等外来元素。  现在,在读入SAS之前,我们必须首先清理原始数据。这需要相当长的时间。有没有什么办法可以在读取数据之前清理SAS系统内的数据。如果我们可以使用SAS代码纠正数据,它将节省大量时间。

以下是示例:

期间1:我以此格式获取了Data1.csv中的数据。在B列中,这是数字,我是“#”& “”。 colummn C,也是数字,我是“g”。如果我使用PROC IMPORT或Infile语句导入Data1.csv,则列B和B中的这些外来元素。 C将保留。这里的问题是如何做到这一点?我可以使用If STATEMENT。但问题是有太多的外来元素(例如,而不是“#”,“。”,“g”,我可能会得到其他外国元素,如“$”,“h”等。)如果有任何方式,我们可以有检测和检测的代码每次我在SAS中导入原始数据时,我都不会使用IF STATEMENT指定它来删除外来元素。

   A    B   C
Name1   1   5
Name2   2   6
Name3   3   4
Name4   #   g
Name5   5   3
Name6   .   6

期间2:在此期间,我获得了DATA2.csv,如下所示。当我使用INFILE语句时,我指定1st A应该使用特定名称读取,然后B指定具有特定名称&然后C.在我得到数据B的第2个时段给出第1个。因此,当SAS读取数据时我是B而不是A.所以,我每次都要检查变量的顺序和先前的相位数据。在使用infile语句读取数据之前纠正它。由于变量的数量太大,以这种方式验证列排序是非常耗时的(并且在时间上令人沮丧)。是否有SAS代码,SAS将自动读取A,&那么B&那么C,即使它不按此顺序?

B   A   C
1   Name1   5
2   Name2   6
3   Name3   4
#   Name4   g
5   Name5   3
.   Name6   6

即使我主要在分析目的中使用SAS。但我可以使用R来清理数据,然后用它在SAS中读取它以进行进一步分析。所以R代码也很有帮助。

感谢。

2 个答案:

答案 0 :(得分:3)

在R中,当您指定列是特定类时,可以提高文件读取的速度。提供示例(3列中间的一个是“字符”,您可以使用此代码:

 dat <- read.csv( filename, colClasses=c("numeric", "character", "numeric"), comment.char="")

“#”和“。”在数字列中遇到时将变为NA值。上面的代码删除了注释字符的默认规范,即“#”。如果你想要“#”和“。”要强制转换为NA_character_的字符列中的条目,您可以使用以下代码:

dat <- read.csv( filename, 
                 colClasses=c("numeric", "character", "numeric"),
                 comment.char="",
                 na.strings=c("NA", ".", "#") )

默认情况下,read.csv()假定header=TRUE设置,但如果使用read.table(),则需要使用您显示的两个文件结构断言header=TRUE。还有其他文档和worked examples of reading Excel data here:但是,我的建议是在您计划和使用CSV传输时执行。你会看到Excel在日期和缺失值方面做得更加棘手。建议您将数据格式更改为与POSIX标准一致的自定义“yyyy-mm-dd”,在这种情况下,您还可以指定“日期”分类列并跳过转换字符分类列的过程默认的Excel格式(所有这些都是坏的)到日期。

答案 1 :(得分:2)

是的,您可以使用SAS进行您可能想到的任何“数据清理”。 SAS DATA步骤语言充满了这样的功能,但没有灵丹妙药;你需要自己编写代码。

csv文件只是一个纯文本文件(与xls文件非常不同)。通常,csv文件中的第一行包含列名,数据以第二行开头。如果使用PROC IMPORT,SAS将使用第一行构造变量名称,并尝试通过扫描文件的前几行来确定数据类型。例如:

proc import datafile='c:\temp\somefile.csv'
     out=SASdata
     dbms=csv replace;
run;

或者,您可以使用数据步骤读取文件。这将要求您事先知道文件布局。例如:

data SASdata;
   infile 'c:\temp\somefile.csv' dsd firstobs=2 lrecl=32767 truncover;
   informat A $50.; /* A character variable with max length 50 */
   informat B yymmdd10.; /* A date presented like 2012-08-25 */
   informat C dollar12.; /* A number containing dollar sign, commas, or decimals */

   input A B C;  /* The order of the variables in the file */

   if B = . then B = today(); /* A possible data cleaning statement */
run;

请注意,INPUT语句控制文件中变量的顺序。关键是您使用的代码必须与您处理的每个文件的布局相匹配。

这些只是一般性评论。如果您遇到问题,请回复一个更具体的问题。

更新问题的更新:原始数据文件中的变量必须按照每个文件中存在的顺序在INPUT语句中列出。此外,您需要直接定义列类型,并建立他们需要遵循的规则。没有办法自动执行此操作;每个文件都要分开处理。

在这种情况下,假设您的变量是A,B和C,其中A是字符,B和C是数字。该程序可能会处理这两个文件并将它们添加到历史数据集(比方说ALLDATA):

data temp;
   infile 'c:\temp\data1.csv' dsd firstobs=2 lrecl=32767 truncover;
   /* Define dataset variables */
   informat A $50.;
   informat B 12.;
   informat C 12.;
   /* Add a KEEP statement to keep only the variables you want */
   keep A B C;

   input A B C;
run;
proc append base=ALLDATA data=temp;
run;
data temp;
   infile 'c:\temp\data2.csv' dsd firstobs=2 lrecl=32767 truncover;
   informat A $50.;
   informat B 12.;
   informat C 12.;

   input B A C;
run;
proc append base=ALLDATA data=temp;
run;

请注意,每个数据步骤的“数据定义”部分是相同的;唯一的区别是INPUT语句中列出的变量的顺序。请注意,因为变量A和B被定义为数字,所以当读取这些无效字符(#和g)时,这些值将存储为缺失值。

在您的情况下,我将创建一个模板SAS程序,以按照您期望的顺序定义所需的所有变量。然后使用该模板使用该文件中变量的顺序导入每个文件。设置模板程序可能需要一段时间,但要运行它,您只需要修改INPUT语句。