我在excel中有一个数据集,变量包含字符和数字格式的值。
var1 -------- var2
352,45 -----< 34,5
当我将它们导入SAS时,var2会丢失,我怎样才能保留或估算"< 34,5"对于var2?
我使用以下代码导入:
PROC IMPORT OUT= data
DATAFILE= "data1.xlsx"
DBMS=EXCEL REPLACE;
RANGE="Sheet1$";
GETNAMES=YES;
MIXED=YES;
SCANTEXT=YES;
USEDATE=YES;
SCANTIME=YES;
RUN;
答案 0 :(得分:2)
快速回答
使用RegEdit更改Windows注册表项。在我的系统上,Windows 10,x64,Office 2016,条目
...
var r1 = httpClient.GetAsync(url1);
var r2 = httpClient.GetAsync(url2);
var response1 = await r1;
var response2 = await r2;
...
会改为
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel\TypeGuessRow
解释
0
推断列Proc IMPORT DBMS=EXCEL
是数字内容,因为它没有扫描足够多的Excel行来发现有一些非数字内容。因此,当达到非数字内容时,该过程会以缺失值替换它。
你必须
扫描更多行 - Excel
没有var2
选项可用于更改扫描的Excel行数。
Proc IMPORT
使用Microsoft技术读取Excel文件。在SAS版本< 9.2第2阶段,技术是Jet,新版本使用ACE。这些技术中的每一种都使用 Windows 注册表来获取参数Proc IMPORT DBMS=Excel
,该参数是在推断列是字符,数字或日期之前应扫描的行数。当参数值为 0 时,在推断之前会扫描所有行。
SAS Documentation“SAS /ACCESS®9.4与PC文件的接口:参考,第四版”章节“Microsoft Excel工作簿文件”详细说明了需要更改的 Windows 注册表项在系统和Office安装上。正如快速中提到的,我的系统有
TypeGuessingRows
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel\TypeGuessRow
行的默认值已更改为8
。
奖励:扫描更多行 - 分隔文件
这些文本文件的字段由逗号,制表符或其他字符分隔。
可以使用GUESSINGROWS 语句 强制 0
扫描所有行
Proc IMPORT DBMS=CSV
第2步 - 后处理
以下是一些示例代码,显示了如何将已知的“棘手”列转换为相同的命名数字列。 规则是值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;
列$1
,其中包含值var2_relation
,=
或{{ 1}}。或者,您可以在执行input()转换之前压缩值,删除所有非数字字符。
如果您在编写对所有变量执行相同转换的解决方案时遇到问题,那将是另一个问题。
答案 1 :(得分:0)
正如其他人所指出的那样,可能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;
答案 2 :(得分:-1)
您是否考虑过使用infile而不是proc import? 此外,如果数字和字符都在同一个colomn中,则需要将其强制为字符。
http://www2.sas.com/proceedings/forum2008/166-2008.pdf
下面的代码是我从循环中获得的一个示例,但您应该能够弄明白。请注意,当在colile语句中跟随colomn后,它会强制colomn成为字符!
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;