SAS-使用输入将现有字符变量值更改为数字

SAS-使用输入将现有字符变量值更改为数字,sas,type-conversion,Sas,Type Conversion,有一个名为var1的变量,它有两种值,都是字符串。一个是ND,另一个是0-100中的数字,作为字符串。我想将ND转换为0,将字符串转换为数值,例如,将1character转换为1numeric 以下是我的代码尝试: data cleaned_up(drop = exam_1); set dataset.df(rename=(exam1=exam_1)); select (exam1); when ('ND') do; exam1 = 0; end;

有一个名为var1的变量,它有两种值,都是字符串。一个是ND,另一个是0-100中的数字,作为字符串。我想将ND转换为0,将字符串转换为数值,例如,将1character转换为1numeric

以下是我的代码尝试:

data cleaned_up(drop = exam_1);
    set dataset.df(rename=(exam1=exam_1));
select (exam1);
    when ('ND') do;
        exam1 = 0;
    end;
    when ; 
        exam1 = input(exam_1,2.);
    end;
    otherwise;
end;

显然不起作用。我做错了什么

您正在使用selectexam1,而它应该是selectexam\u 1。您可以使用select实现此目的,但我认为简单的if条件可以更轻松地解决此问题:

data test;
    length source $32;
    do source='99', '34.5', '105', 'ND';
        output;
    end;
run;

data result(drop = convertedValue);
    set test;

    if (source eq 'ND') then do;
        result = 0;
    end;
    else do;
        convertedValue = input(source,??best.);
        if not missing(convertedValue) then do;
            if (0 <= round(convertedValue, 1E-12) <= 100) then do;
                result = convertedValue;
            end;
        end;
    end;
run;
输入源,?最佳。尝试将源转换为数字,如果失败(例如,值包含某个单词),则不会打印错误并继续执行

roundconvertedValue,1E-12用于避免比较过程中的精度误差。如果你想绝对安全地做这件事,你必须使用

if (0 < round(convertedValue,1E-12) < 100
    or abs(round(convertedValue,1E-12)) < 1E-10 
    or abs(round(convertedValue-100,1E-12)) < 1E-10
) 

您正在使用selectexam1,而它应该是selectexam\u 1。您可以使用select实现此目的,但我认为简单的if条件可以更轻松地解决此问题:

data test;
    length source $32;
    do source='99', '34.5', '105', 'ND';
        output;
    end;
run;

data result(drop = convertedValue);
    set test;

    if (source eq 'ND') then do;
        result = 0;
    end;
    else do;
        convertedValue = input(source,??best.);
        if not missing(convertedValue) then do;
            if (0 <= round(convertedValue, 1E-12) <= 100) then do;
                result = convertedValue;
            end;
        end;
    end;
run;
输入源,?最佳。尝试将源转换为数字,如果失败(例如,值包含某个单词),则不会打印错误并继续执行

roundconvertedValue,1E-12用于避免比较过程中的精度误差。如果你想绝对安全地做这件事,你必须使用

if (0 < round(convertedValue,1E-12) < 100
    or abs(round(convertedValue,1E-12)) < 1E-10 
    or abs(round(convertedValue-100,1E-12)) < 1E-10
) 

您的代码有几个问题。将rename语句作为数据集选项放置在输入数据集上,将在读入数据之前执行重命名。因此exam1将不存在,因为它现在被称为exam_1。这仍将被定义为字符列,因此输入函数无法工作

您需要保留现有列,创建一个新的数值列来进行转换,然后删除旧列并重命名新列。这可以作为针对输出数据集的数据集选项来完成

tranwrd函数将把所有出现的“ND”替换为“0”,然后使用带有best12信息的输入将所有数据作为数字读入。在读取数字(例如2)时,不必指定长度。对于2位数字,3。对于3位数字等

data cleaned_up (drop=exam1 rename=(exam_1=exam1));
set df;
exam_1 = input(tranwrd(exam1,'ND','0'),best12.);
run;

您的代码有几个问题。将rename语句作为数据集选项放置在输入数据集上,将在读入数据之前执行重命名。因此exam1将不存在,因为它现在被称为exam_1。这仍将被定义为字符列,因此输入函数无法工作

您需要保留现有列,创建一个新的数值列来进行转换,然后删除旧列并重命名新列。这可以作为针对输出数据集的数据集选项来完成

tranwrd函数将把所有出现的“ND”替换为“0”,然后使用带有best12信息的输入将所有数据作为数字读入。在读取数字(例如2)时,不必指定长度。对于2位数字,3。对于3位数字等

data cleaned_up (drop=exam1 rename=(exam_1=exam1));
set df;
exam_1 = input(tranwrd(exam1,'ND','0'),best12.);
run;

尝试使用ifc函数,然后将其转换为数值变量

data have;
input x $3.;
_x=input(ifc(x='ND','0',x),best12.);
cards;
3
10
ND
;

尝试使用ifc函数,然后将其转换为数值变量

data have;
input x $3.;
_x=input(ifc(x='ND','0',x),best12.);
cards;
3
10
ND
;

只是为了添加一条注释,我不知道在第二个when语句中放什么,可以使它看起来像0-100,因为0-100不是数字…只是为了添加一条注释,我不知道在第二个when语句中放什么,可以使它像0-100,因为0-100不是数字…使用时有任何潜在问题吗??OP也应该知道吗?嗨,我不知道在使用“?”修饰符时有什么潜在的问题。它不会打印无效值的消息,也不会设置自动错误变量。我想如果OP想要看到无效值,可以添加另一个else条件来处理convertedValue丢失的情况,如果数字超出0-100范围,则可以添加另一个else条件。我选择另一个答案,因为从可读性角度来看,代码很简洁。但这也是一个很好的答案。谢谢。使用时是否存在任何潜在问题??OP也应该知道吗?嗨,我不知道在使用“?”修饰符时有什么潜在的问题。它不会打印无效值的消息,也不会设置自动错误变量。我想如果OP想要看到无效值,可以添加另一个else条件来处理convertedValue丢失的情况,如果数字超出0-100范围,则可以添加另一个else条件。我选择另一个答案,因为从可读性角度来看,代码很简洁。但这也是一个很好的答案。非常感谢。