将带有字符和数值的变量从excel导入SAS
我在excel中有一个数据集,变量包含字符和数字格式的值 var1------var2将带有字符和数值的变量从excel导入SAS,excel,sas,character,numeric,Excel,Sas,Character,Numeric,我在excel中有一个数据集,变量包含字符和数字格式的值 var1------var2 352,45------快速回答 使用RegEdit更改Windows注册表项。在我的系统Windows 10、x64、Office 2016上 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel\TypeGuessRow 将更改为 0 解释 Proc IMPORT DBMS=
352,45------快速回答 使用RegEdit更改Windows注册表项。在我的系统Windows 10、x64、Office 2016上
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel\TypeGuessRow
将更改为
0
解释
Proc IMPORT DBMS=EXCEL
正在推断列var2
是数值内容,因为它没有扫描足够的EXCEL行以发现某些非数值内容。因此,当到达非数字内容时,该过程将用缺少的值替换该推断
你必须
- 使导入将这些列(变量)定义为字符类型
- 执行将预期数值变量转换为实际数值变量的转换
Proc IMPORT
选项
Proc IMPORT DBMS=Excel
在Windows中使用Microsoft技术读取Excel文件。在SAS版本中,您是否想过使用infle而不是proc导入?
此外,如果数字和字符都在同一列中,则需要将其强制为个字符
下面的代码是我从一个循环中得到的一个示例,但是您应该能够理解它。请注意,在infle语句中,当一个列后跟$时,它会强制该列为字符
filename file&i "&fdir"; /*THIS ASSIGN FILE NAME RELATED WITH THE DIRECTORY IN PREVIOUS FILE*/
data &name; /*USE THE FULL PATH OF THE FILE NEEDED AS PER 1ST TABLE*/
LENGTH BAN $10.;
LENGTH SUBSCRIBER_NO $10.;
LENGTH TRANSACTION_DATE $18.;
LENGTH OPT1 $18.;
INFILE file&i delimiter = ',' MISSOVER DSD LRECL=32767 FIRSTOBS=2 flowover;
input SUBSCRIBER_NO $ BAN $ OPT1 $ TRANSACTION_DATE $ TRANSACTION_TYPE $ ITEM_ID $ MSID $ NIN1 $ ACTIVATION_TYPE $ STORE_CODE $ OPT8 $ OPT10 $ OPT9 $ WES $ BILL_CYCLE $ LANGUAGE_CODE $ REGION $ COMPANY_CODE $ PRICE_PLAN $ COMMIT_START_DATE $ SYS_CREATION_DATE $ RENEWAL_DATE $ ESN_TYPE $ ACCOUNT_TYPE $ EFFECTIVE_DATE $ INIT_ACTIVATION_DATE $ TENURE $ DATA $ PRICE_PLAN_DATA $ OPT3 $ PRICE_PLAN_DESC $ MSF $ PRICE_PLAN_SERIES $ ACTIVATION_DATE $ OPT5 $ TERM_STATUS $ OPT4 $ FIRST_NAME $ LAST_BUSINESS_NAME $ ADDRESS_ATTENTION $ USER_NAME $ ADDRESS_NAME_1 $ ADDRESS_NAME_2 $ ADDRESS_NAME_3 $ CITY $ province $ POSTAL_CODE $ home_no $ work_no $ MKT_ACCOUNT_TYPE $ ESN_EFFECTIVE_DATE $ CABLE_FOOTPRINT $ COMMON_IND $ CS_VIP_CLASS $ OPT2 $ OPT6 $ OPT7 $ KEYCODE $ CAMPAIGN_CODE $ CAMPAIGN_CYCLE $ CAMPAIGN_DATE $ CAMPAIGN_DESCRIPTION $ CAMPAIGN_TYPE $ EMAIL $ MOP $ SERIAL_NUMBER $ ACTIVATION_SUB_TYPE $ SALES_REP $ ;
run;
data import;
set %if ne 1 %then import;
&name;
run;
%let i = %eval(&i+1);
filename file&i clear;
正如其他人所注意到的,Excel引擎可能没有向下扫描足够的距离来查找字符值 XLSX引擎,我相信是9.3中的新引擎,在9.4中基本上完全支持导入和导出功能,可以更好地扫描变量类型。它相当容易使用,只需将
DBMS=EXCEL
交换到DBMS=XLSX
。如果您有(例如)GETNAMES=NO
,则它不会完全相同,但对于大多数用途,它是相同的
PROC IMPORT OUT= data
DATAFILE= "data1.xlsx"
DBMS=XLSX REPLACE;
SHEET="Sheet1";
GETNAMES=YES;
RUN;
如何导入数据?日志显示了什么?我已将代码添加到我的帖子中。您是否尝试使用
XLSX
引擎而不是EXCEL
引擎?另请参见。谢谢,但是猜测行不适用于EXCEL文件,而仅适用于csv。是否有任何东西可以为excel执行相同的工作?var2首先显示在哪个excel行?它仅存在于excel文件的第27行和第30行中。您必须更改Windows注册表设置。请参阅更新的答案我认为,如果使用XLSX引擎而不是EXCEL引擎,则无需更改它检查的行数。它应该检查整个列。只有先将Excel数据导出到csv文件,这才有效。谢谢!在您链接的此网页中,当office版本为2013或更高版本时,有更改windows注册表设置的信息,但没有2016版本的信息。我的office版本是2016年,你知道如何更改注册表设置吗?你可以在RegEdit中浏览或使用RegEdit查找功能查找TypeGuessingRows
的条目。什么不起作用??DBMS=XLSX在9.4中确实可以工作。它没有解决您的字符/数字问题吗?这是我通过使用XLSX获得的日志:(Excel不会出现这种情况)3365 PROC IMPORT OUT=data1 3366 DATAFILE=“data.XLSX”3367 DBMS=XLSX REPLACE;3368 SHEET=“Sheet1$”;3369 GETNAMES=是;3370次;错误:在电子表格中找不到工作表注意:SAS系统由于错误而停止处理此步骤。注意:使用的过程导入(总处理时间):实时0.04秒cpu时间0.00秒如果只需要第一张工作表,则不需要sheet=
语句。您确定该文件是实际的XLSX文件吗?复制并将扩展名更改为ZIP,然后检查是否可以看到ZIP文件中的XML文件。现在,我可以看到数字和字符值,但当我尝试将数据集与其他数据集组合时,会出现以下错误,错误:变量day_u14已定义为字符和数字。错误:变量day_2已定义为字符和数字。我使用put(day_2,6.)将所有字符转换为字符,但仍然得到相同的错误
Proc IMPORT --all my options-- out=import_raw;
GUESSINGROWS=MAX; * statement;
run;
data import;
set import_raw (rename=var2=var2_raw);
if var2_raw =: '<' then
var2 = input(substr(var2_raw,2), best12.);
else
var2 = input(var2_raw,best12.);
drop var2_raw;
run;
filename file&i "&fdir"; /*THIS ASSIGN FILE NAME RELATED WITH THE DIRECTORY IN PREVIOUS FILE*/
data &name; /*USE THE FULL PATH OF THE FILE NEEDED AS PER 1ST TABLE*/
LENGTH BAN $10.;
LENGTH SUBSCRIBER_NO $10.;
LENGTH TRANSACTION_DATE $18.;
LENGTH OPT1 $18.;
INFILE file&i delimiter = ',' MISSOVER DSD LRECL=32767 FIRSTOBS=2 flowover;
input SUBSCRIBER_NO $ BAN $ OPT1 $ TRANSACTION_DATE $ TRANSACTION_TYPE $ ITEM_ID $ MSID $ NIN1 $ ACTIVATION_TYPE $ STORE_CODE $ OPT8 $ OPT10 $ OPT9 $ WES $ BILL_CYCLE $ LANGUAGE_CODE $ REGION $ COMPANY_CODE $ PRICE_PLAN $ COMMIT_START_DATE $ SYS_CREATION_DATE $ RENEWAL_DATE $ ESN_TYPE $ ACCOUNT_TYPE $ EFFECTIVE_DATE $ INIT_ACTIVATION_DATE $ TENURE $ DATA $ PRICE_PLAN_DATA $ OPT3 $ PRICE_PLAN_DESC $ MSF $ PRICE_PLAN_SERIES $ ACTIVATION_DATE $ OPT5 $ TERM_STATUS $ OPT4 $ FIRST_NAME $ LAST_BUSINESS_NAME $ ADDRESS_ATTENTION $ USER_NAME $ ADDRESS_NAME_1 $ ADDRESS_NAME_2 $ ADDRESS_NAME_3 $ CITY $ province $ POSTAL_CODE $ home_no $ work_no $ MKT_ACCOUNT_TYPE $ ESN_EFFECTIVE_DATE $ CABLE_FOOTPRINT $ COMMON_IND $ CS_VIP_CLASS $ OPT2 $ OPT6 $ OPT7 $ KEYCODE $ CAMPAIGN_CODE $ CAMPAIGN_CYCLE $ CAMPAIGN_DATE $ CAMPAIGN_DESCRIPTION $ CAMPAIGN_TYPE $ EMAIL $ MOP $ SERIAL_NUMBER $ ACTIVATION_SUB_TYPE $ SALES_REP $ ;
run;
data import;
set %if ne 1 %then import;
&name;
run;
%let i = %eval(&i+1);
filename file&i clear;
PROC IMPORT OUT= data
DATAFILE= "data1.xlsx"
DBMS=XLSX REPLACE;
SHEET="Sheet1";
GETNAMES=YES;
RUN;