R-根据存储在其他列中的公式计算列

时间:2018-08-17 16:18:33

标签: r sas

我的表包含数据rebate calculation

在R中,如何添加新的“折扣”列,其值基于“公式”列的计算?

以下代码有效,但结果错误。

test_df <- data.frame(
  din_pin = c(12345678, 23456789, 2789),
  eff_price = c(10, 6, 0.6),
  qty = c(100, 100, 1000),
  list_price = c(12, 7, 0.85),
  form_price = c(0, 5.5, 0.65),
  formula = c("(eff_price - list_price)*qty", 
              "(form_price - list_price)*qty", 
              "(eff_price - list_price)*qty")
)

for (row in 1:nrow(test_df)){
  formula_text <- as.character(test_df[row, "formula"])
  print(formula_text)
  test_df$rebate[row] <- eval(parse(text = formula_text), test_df)
}

如果我将公式值更改为此:

test_df <- data.frame(
  din_pin = c(12345678, 23456789, 2789),
  eff_price = c(10, 6, 0.6),
  qty = c(100, 100, 1000),
  list_price = c(12, 7, 0.85),
  form_price = c(0, 5.5, 0.65),
  formula = c("(test_df$eff_price[row] - test_df$list_price[row])*test_df$qty[row]", 
              "(test_df$form_price[row] - test_df$list_price[row])*test_df$qty[row]", 
              "(test_df$eff_price[row] - test_df$list_price[row])*test_df$qty[row]")
)

结果正确。

但是,我希望代码是通用的(独立于数据框)。

我在SAS中完成了类似的任务,

data test;
    infile datalines dsd dlm = "," missover;

    input din_pin       :8.
          eff_price     :9.4
          qty           :8.
          list_price    :9.4
          former_price  :9.4
          formula       :$50.
    ;

datalines;
12345678, 10.0000, 100, 12.0000, 0.0000, (eff_price - list_price)*qty
23456789, 6.0000, 100, 7.0000, 5.5000, (former_price - list_price)*qty
2789, 0.60000, 1000, 0.850000, 0.6500, (eff_price - list_price)*qty
;
run;

data _null_;
    set test end=end;
    count+1;
    call symputx('rebate_formula'||left(count),compress(formula));
    if end then call symputx('max',count);
run;

%macro calculate_rebate;
    data rebate;
        set test;
        %do i = 1 %to &max;
            if _n_ = &i then do;
                rebate = &&rebate_formula&i;
            end;
        %end;
    run;
%mend calculate_rebate;

%calculate_rebate;

proc print data = rebate;
run;

我认为在R中应该更容易。我就是做错了。

2 个答案:

答案 0 :(得分:0)

问题是评估程序不知道您要评估的行。尝试将其更改为:

test_df$rebate[row] <- eval(parse(text = formula_text), test_df[row,])

答案 1 :(得分:0)

感谢DomPazz。

这是修改后的代码:

test_df <- data.frame(
  din_pin = c(12345678, 23456789, 2789),
  eff_price = c(10, 6, 0.6),
  qty = c(100, 100, 1000),
  list_price = c(12, 7, 0.85),
  form_price = c(0, 5.5, 0.65),
  formula = c("(eff_price - list_price)*qty", 
              "(form_price - list_price)*qty", 
              "(eff_price - list_price)*qty")
)

for (row in 1:nrow(test_df)){
  formula_text <- as.character(test_df[row, "formula"])
  print(formula_text)
  test_df$rebate[row] <- eval(parse(text = formula_text), test_df[row,])
}