关于SAS Data Step用外部文本文件指定Keep变量的方法咨询
Hey there! Let's break down your question step by step—first, we'll fix the issues in your current code, then look at more robust and efficient ways to get what you need.
What's Wrong with Your Current Code?
Your approach has two key problems that will throw errors in SAS:
- Misusing
%include: The%includestatement inserts the content of the text file directly into your SAS code as executable statements. Since your file has tab-separated variable names (not valid SAS syntax), SAS will try to run those names as code and immediately throw a syntax error. - Invalid Macro Variable Syntax:
keep = &contents1.txtis incorrect on two counts:- You never defined a macro variable named
contents1, so SAS won't know what to expand here. - The
.txtafter&contents1is treated as part of the macro variable name, which doesn't exist anyway.
- You never defined a macro variable named
Correct Implementation
The right approach is to first read the tab-separated variable names from your text file into a single macro variable (formatted as space-separated names, since that's what SAS expects for the keep option). Here's a straightforward way to do this:
/* Step 1: Read the tab-separated variable names into a macro variable */ data _null_; infile "/location/contents1.txt" dlm='09'x truncover; /* '09'x represents a tab character */ length keep_vars $32767; /* Allocate enough space for 250 variable names */ input varname $ @@; /* @@ tells SAS to keep reading variables until the line ends */ keep_vars = catx(' ', keep_vars, varname); /* Join variables with spaces */ call symputx('keep_vars', keep_vars); /* Store the result in a macro variable */ run; /* Step 2: Use the macro variable to subset your dataset */ data new_cust_base(keep = &keep_vars); set cust_base; run;
How This Works:
- The
infilestatement usesdlm='09'xto split the text file's content by tabs. input varname $ @@reads every variable name in the file (even if they're on multiple lines, though your file seems to have one line of tab-separated names).catx(' ', keep_vars, varname)builds a space-separated string of valid variable names, which is exactly what thekeepoption needs.call symputxsaves this string to the macro variable&keep_vars, which we then use in thekeepstatement.
More Robust (Optimal) Version
If you want to avoid warnings or errors from variables in your text file that don't exist in cust_base, add a check to only keep variables that are actually present in your source dataset:
/* Step 1: Get a list of all variables in cust_base */ proc contents data=cust_base out=cust_var_list(keep=name) noprint; run; /* Step 2: Read the text file, filter for existing variables, and build the macro variable */ data _null_; length keep_vars $32767; /* Create a hash table to quickly check if a variable exists in cust_base */ if _n_ = 1 then do; declare hash var_check(dataset:'cust_var_list'); var_check.definekey('name'); var_check.definedone(); end; infile "/location/contents1.txt" dlm='09'x truncover; input varname $ @@; /* Only add the variable to our list if it exists in cust_base */ if var_check.check(key:varname) = 0 then do; keep_vars = catx(' ', keep_vars, varname); end; call symputx('keep_vars', keep_vars); run; /* Step 3: Subset the dataset */ data new_cust_base(keep = &keep_vars); set cust_base; run;
This version uses a hash table for fast lookups, ensuring you only keep variables that are present in cust_base—no more annoying warnings about missing variables!
内容的提问来源于stack exchange,提问作者IndigoChild

