【问题标题】:Generating models from a car type simulation in SAS?从 SAS 中的汽车类型模拟生成模型?
【发布时间】:2015-04-10 15:19:30
【问题描述】:

我正在运行一个模拟来预测汽车经销商的库存。经销商在 10% 的时间里销售零辆汽车,一辆汽车 50%,两辆汽车 30%,三辆汽车 10%。在销售的这些汽车中,50% 是轿车,30% 是 SUV,20% 是卡车。此外,所售汽车的型号如下:

  • 轿车:30% 为“S”,40% 为“SE”,30% 为“SEL”
  • SUV:25% 为“S”,35% 为“SE”,40% 为“SEL”
  • 卡车:50% 为“S”,30% 为“SE”,20% 为“SEL”

我正在尝试生成这些最后的模型分布,但我的代码整天都打印“S”。各位能给点建议吗?谢谢!

这是文本中的代码:

data cars (drop=perc_sales car_type_perc subtype_perc);
format date date9.;
    date='01Jan2016'd;
    do until (date > '31Dec2016'd);
        if 
            weekday(date) not in (1)
            and date not in ('01Jan2016'd,'04Jul2016'd,'25Dec2016'd)
            then output;
        date=intnx('day',date,1);
    S_price1 = 15000+200*rand('normal');    *Sedan;
    S_price2 = 30000+500*rand('normal');    *SUV;
    S_price3 = 25000+300*rand('normal');    *Truck;
    perc_sales = rand('uniform');
    car_type_perc = rand('uniform');
    subtype_perc = rand('uniform');
        if 0 < perc_sales <= 0.1 then Ncars = 0;                * 10% chance zero cars sold;
        if 0.1 < perc_sales <= 0.6 then Ncars = 1;              * 50% chance one car sold;
        if 0.6 < perc_sales <= 0.9 then Ncars = 2;              * 30% chance two cars sold;
        if 0.9 < perc_sales <= 1 then Ncars = 3;                * 10% chance three cars sold;
        if 0 < car_type_perc <= 0.5 then type = 'Sedan';        * 50% of cars sold are sedans;
        if 0.5 < car_type_perc <= 0.8 then type = 'SUV';        * 30% of cars sold are SUVs;
        if 0.8 < car_type_perc <= 1 then type = 'Truck';        * 20% of cars sold are trucks;
        if type = 'Sedan' and 0 < rand('uniform') <= 0.3 then model = 'S';
        if type = 'Sedan' and 0.3 < rand('uniform') <= 0.7 then model = 'SE';
        if type = 'Sedan' and 0.7 < rand('uniform') <= 1 then model = 'SEL';
        if type = 'SUV' and 0 < rand('uniform') <= 0.25 then model = 'S';
        if type = 'SUV' and 0.25 < rand('uniform') <= 0.6 then model = 'SE';
        if type = 'SUV' and 0.6 < rand('uniform') <= 1 then model = 'SEL';
        if type = 'Truck' and 0 < rand('uniform') <= 0.5 then model = 'S';
        if type = 'Truck' and 0.5 < rand('uniform') <= 0.8 then model = 'SE';
        if type = 'Truck' and 0.8 < rand('uniform') <= 1 then model = 'SEL';
    end;
run;

【问题讨论】:

  • 代码应该作为文本输入,而不是图片 - 我无法将图片复制并粘贴到我的编辑器中(好吧,让它做任何有用的事情)。
  • 很抱歉 - 我不知道我可以使用 ctrl+k 来更轻松地粘贴。

标签: model statistics sas simulation


【解决方案1】:

首先,您的变量model 的长度为$1,因为第一次看到它时,它是'S'。始终为变量定义长度。

其次,您需要将rand('uniform') 分配给一个变量以进行type 计算。上面的代码有时不应该分配模型,因为每次调用都是一个新的随机数。您对car_type_perc 等这样做是正确的,但对于类型却不是。有时没有分配类型;您是在一个数据步骤循环迭代中执行此操作的,因此您可能不会注意到这一点,有时除了初始行之外,但它目前并没有按照您的意愿执行。

第三,为什么你的输出在循环的顶部?因为你排除了 1 月 1 日,所以它并没有真正破坏任何东西,但是你在计算任何东西之前就已经输出了;这样做有点奇怪。通常,您要么在该 if 块中添加 continue; 语句,然后在所有其他情况下在循环结束时输出。

第四,您应该添加对call streaminit(#) 的调用(使用您想要的任何正数),以便您的样本可复制。

最后,我认为有更好的方法可以做到这一点(尽管上述方法并不是特别糟糕,只是有点难以维护并且很难始终正确)。创建一个具有此基础的“源”数据集,例如,有 1000 辆汽车非随机分布但与上述匹配(这基本上是 3 个百分比的所有可能组合 - 你可以用少一点的方式完成,但 1000 辆很容易)。然后PROC SURVEYSELECT 使用替换方法将生成您想要的任何大小的样本。 Rick Wicklin 有一本书,用 SAS 模拟数据,并在他的 blog, The DO Loop 上发表了一些很棒的帖子,可能对此有所帮助。

这里有一些小改动,以使其正常工作并使其更简单一些。我会以完全不同的方式来做这件事,因为长长的 IF 语句集很难阅读和维护,但如果这对你有用,那是你的选择。

除上述之外的重大变化:我将您的循环更改为 DO 循环,因为日期是整数并且更易于阅读;添加了STOP,因为这在技术上是必要的(SAS 可以解决它,但你应该拥有它);将 OUTPUT 移到底部,并将 CONTINUE 添加到顶部。还在输出后添加了一个 CALL MISSING 以确保没有任何东西渗入下一行。

data cars (drop=perc_sales car_type_perc subtype_perc);
    format date date9.;  
    length model $3 type $5;
    call streaminit(7);
    do date = '01Jan2016'd to '31Dec2016'd;
        if 
            weekday(date) = 1 or date in ('01Jan2016'd,'04Jul2016'd,'25Dec2016'd)
            then continue;
    S_price1 = 15000+200*rand('normal');    *Sedan;
    S_price2 = 30000+500*rand('normal');    *SUV;
    S_price3 = 25000+300*rand('normal');    *Truck;
    perc_sales = rand('uniform');
    car_type_perc = rand('uniform');
    subtype_perc = rand('uniform');
        if 0 < perc_sales <= 0.1 then Ncars = 0;                * 10% chance zero cars sold;
        if 0.1 < perc_sales <= 0.6 then Ncars = 1;              * 50% chance one car sold;
        if 0.6 < perc_sales <= 0.9 then Ncars = 2;              * 30% chance two cars sold;
        if 0.9 < perc_sales <= 1 then Ncars = 3;                * 10% chance three cars sold;
        if 0 < car_type_perc <= 0.5 then type = 'Sedan';        * 50% of cars sold are sedans;
        if 0.5 < car_type_perc <= 0.8 then type = 'SUV';        * 30% of cars sold are SUVs;
        if 0.8 < car_type_perc <= 1 then type = 'Truck';        * 20% of cars sold are trucks;
        if type = 'Sedan' and 0 < subtype_perc <= 0.3 then model = 'S';
        if type = 'Sedan' and 0.3 < subtype_perc <= 0.7 then model = 'SE';
        if type = 'Sedan' and 0.7 < subtype_perc <= 1 then model = 'SEL';
        if type = 'SUV' and 0 < subtype_perc <= 0.25 then model = 'S';
        if type = 'SUV' and 0.25 < subtype_perc <= 0.6 then model = 'SE';
        if type = 'SUV' and 0.6 < subtype_perc <= 1 then model = 'SEL';
        if type = 'Truck' and 0 < subtype_perc <= 0.5 then model = 'S';
        if type = 'Truck' and 0.5 < subtype_perc <= 0.8 then model = 'SE';
        if type = 'Truck' and 0.8 < subtype_perc <= 1 then model = 'SEL';
        output;
        call missing(of model type ncars);
    end;
    stop;
run;

【讨论】:

  • 我觉得我已经非常接近使用这段代码了 - 我编写它的方式对我来说很直观,我认为它应该可以工作。问题在于九个 if 类型语句。
  • @TimRoberson 你解决了我当时指出的前两个问题吗?
  • 是的,在定义了“模型”的长度之后,代码就按照我想要的方式运行了。它产生与您提供的结果相同的结果。谢谢您的帮助!顺便说一句,调用 streaminit 函数有什么作用?
  • 如果您不修复 9 个 if 语句,它将不会产生正确的数据 - 您并不总是重新分配模型。 CALL STREAMINIT 设置了随机数种子,所以可以保证得到可重现的结果(只要数字相同,就可以得到完全相同的输出)。
猜你喜欢
  • 1970-01-01
  • 2022-01-21
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
  • 2012-08-27
相关资源
最近更新 更多