excel - 导入数值列中包含无效字符的数据

标签 excel csv sas

数据结构:我有一个可以读取为 Excel 或 CSV 文件的数据集。它具有以下变量类型:日期、时间、数字变量,以及错误地将字符附加到数字的数字变量 - 例如。 -0.011* 和 0.023954029324)(末尾的括号在单元格中) - 由于写入文件的程序出错。每条记录之间也有空行,删除所有这些是不现实的,因为我有数百个文件要管理。

数据问题:我们已确定某些值在字符之前是正确的(即,只要删除星号,-0.011 就是正确的),而其他值,例如 0.023954029324)则完全不正确,应该丢失。请不要评论这个问题,因为它超出了我的控制范围,此时我所能做的就是管理数据,直到错误得到修复并且字符值停止写入文件。

SAS的问题:

1) 如果我将 PROC IMPORT 与 Excel 文件一起使用,SAS 使用前八行(CSV 文件为 20 行)来确定变量是数字还是字符。如果括号的星号没有出现在前 20 行中,则 SAS 表示该变量是数字的,然后会丢失任何后面的带有字符值的单元格。这在星号的情况下是不行的,因为我想保留值的数字部分并在以后的数据步骤中删除星号。使用 PROC IMPORT 导入 Excel 文件不允许使用 GUESSINGROWS 选项(与 CSV 文件一样,请参见下文)。编辑:另外, MIXED=YES 选项不起作用(请参阅下面的评论 - 仍然需要更改 SAS 使用的行数,对我来说,这意味着这个选项......什么?)。

2) 如果我将 PROC IMPORT 与 CSV 文件一起使用,我可以指定 GUESSINGROWS=32767,我会非常兴奋,因为它会确定带有星号的变量是字符并保留星号。但是,非常奇怪的是,它不再将带括号的变量确定为字符(就像导入 Excel 文件时只要括号在前 20 行中那样),而是删除字符并将值四舍五入到最接近的整数(0.1435980234 变为 0,1.82149023843 变为 2,等等)。这太粗略的舍入 - 我需要保留小数位。而且,最重要的是,括号现在不见了,所以我不能丢失适当的单元格。我不知道是否有办法使 SAS 不四舍五入和/或保持括号。对我来说,这是不一致的行为——为什么在这种情况下星号而不是括号被认为是一个字符?此外,当我读入带有 PROC IMPORT 的 Excel 文件(如 (1) 中所述)时,它可以处理带有括号(如果它们出现在前 20 行中) - 另一个不一致之处。

3)如果我使用INFILE,那么 - 我尝试读取的每个变量都会出错 - 这个过程对于数据的变化方式过于敏感和不稳定(我必须为空白编写一个解决方法数据线)。

终极目标(请注意,此代码将在宏中自动运行,如果重要的话):

1)将日期变量读取为日期

2) 将时间变量读取为时间

3) 能够将该变量的任何单元格中存在的带有字符的变量(即使在 20 行之后)识别为字符变量并维护单元格中的值(即不要舍入/删除字符)。这可以通过先验告诉 SAS 让某个变量集成为字符(在我摆脱字符/使单元格丢失后,我会将它们更改为数字),或者通过 SAS 自己识别带有字符的变量。

最佳答案

  • SAS 实际上默认使用前 8 行。这是在注册表设置中定义的,TYPEGUESSROWS - 通常存储在 HKLM\Software\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel\TypeGuessRows\(或 insert-your-office-version-there)。将该值更改为 FFFF(十六进制)/65536(十进制)或其他一些较大的数字,或零以搜索最大行数(超过 16000 位 - 很难找到确切的数字)。
  • 对于 CSV 文件,您可以编写数据步骤导入来控制每个变量的格式。查看这一点的最简单方法是运行 PROC IMPORT,然后检查您的日志;日志将包含用于在数据步骤中读取文件的完整代码。然后根据需要修改信息。你说你在使用 Infile 方法时遇到了太多麻烦,所以也许这对你不起作用,但通常你可以解决任何不一致的问题——如果你的文件不一致,听起来你会做大量的手动工作反正。这也为您提供了正确读取日期/时间变量的选项。
  • 您还可以将 PROC IMPORT/CSV 用于日志,将日志写入文件,然后将其读入并自行生成新的导入代码 - 甚至可以关闭生成文件的 proc 内容,进行已知修改。

  • 不确定您对日期/时间的要求是什么,因为您在问题的第一部分没有提及它的问题。

    您还有一个选择是在读入之前清除字符(来自 CSV)。这很简单,如果它真的只是数字和逗号(以及小数和负号):
    data mydata;
    infile myfile /*options*/;
    input @@;
    length infileline $32767; *or your longest reasonable line;
    infileline = compress(_infile_,'.-','kd');
    run;
    
    data _null_;
    set mydata;
    file myfile /*options*/ /*or a new file if you prefer */;
    put @1 infileline $32767.; *or your longest reasonable line;
    run;
    

    然后使用 proc import 读取该新文件。我将它分成两个数据步骤,以便您可以看到它,但您可以将它们组合成一个以便于运行 - 在 SAS 文档中查找“就地更新文件”。您还可以使用特定于操作系统的工具来完成此清理;例如,在 Unix 上,一个简短的 awk 脚本可以轻松删除行为不端的字符。

    关于excel - 导入数值列中包含无效字符的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17815490/

    相关文章:

    sas - 如何设置主键 | SAS工作室

    excel - 获取已登录的 Office 365 用户 ID

    excel - 在 Workbook_New 上显示表单

    Excel VBA 使用 CDO 添加附件时出错。消息 "Object doesn' t 支持此属性或方法"

    python - 将 NDArray 写入 JSON 和 .CV 文件

    sas - 如何按高度而不是按字母顺序对条形图的条形进行排序

    c# - EPPlus:检测并处理 "number stored as text"

    python - 使用 Python 3.5 从 CSV 文件的两列中删除特定字符

    python - 将 SAV 转换为 CSV

    sas - Proc 制表 rowpctn 单独列百分比