Function 如何从SAS中给定均值和SD的对数正态分布生成随机数?

Function 如何从SAS中给定均值和SD的对数正态分布生成随机数?,function,macros,sas,distribution,random-sample,Function,Macros,Sas,Distribution,Random Sample,张文平(温迪) SASRAND“基本上给出了“标准”分布 作者描述了一个有趣的SAS%rndnmb宏,用于从“非标准”发行版生成数据。不幸的是,中的代码不可用。所以,我敢自己做 如果我正确理解维基百科,y来自对数正态分布,如果 y=exp^(μ+σ*Z)。 以下公式连接非对数样本值的均值和方差: mu=ln((平均数^2)/(sqrt(方差+平均数^2)) 和 西格玛=sqrt(ln(1+(方差)/(均值^2))) 如果正确,当 Z来自标准正态分布Z,μ'=0,σ'=1 最后,如果 y=exp^

张文平(温迪) SAS
RAND
“基本上给出了“标准”分布

作者描述了一个有趣的SAS
%rndnmb
宏,用于从“非标准”发行版生成数据。不幸的是,中的代码不可用。所以,我敢自己做

如果我正确理解维基百科,y来自对数正态分布,如果
y=exp^(μ+σ*Z)。
以下公式连接非对数样本值的均值和方差:
mu=ln((平均数^2)/(sqrt(方差+平均数^2))

西格玛=sqrt(ln(1+(方差)/(均值^2)))

如果正确,当
Z来自标准正态分布Z,μ'=0,σ'=1

最后,如果
y=exp^(ln((平均数^2)/(sqrt(方差+平均数^2))+sqrt(ln(1+(方差)/(平均数^2)))*Z) ?

我的SAS代码是:
/*我在这里使用StdDev^2表示法而不是方差。*/

数据非日志规范;

nonsln=exp(1)**(log((平均值**2)/(sqrt(标准差^2+平均值**2))+
sqrt(对数(1+(标准差^2)/(平均值**2))*rand('UNIFORM');

RUN;

参考文献:
RAND
Rick Wicklin的函数:
如果你想从标准正态分布中提取
Z
,你不应该通过调用
RAND('normal')
而不是
RAND('UNIFORM')

如果你想从标准正态分布中提取
Z
,你不应该通过调用
RAND('normal')来获取它吗
而不是
RAND('UNIFORM')

如果你想从标准正态分布中提取
Z
,你不应该通过调用
RAND('normal')
而不是
RAND('UNIFORM')来获得它吗

如果你想从标准正态分布中提取
Z
,你不应该通过调用
RAND('normal')
而不是
RAND('UNIFORM')来获得它吗

您需要的是逆累积分布函数。这是一个函数,它是整个域上分布的归一化积分的逆函数。因此,0%是最负的可能值,100%是最正的可能值。实际上,尽管您可能会平静到0.01%和99.99%左右像这样,否则对于很多分布,你会得到无穷大

然后,您只需要随机选择一个范围(0,1)内的数字,并将其插入函数。记住钳制它

double CDF = 0.5 + 0.5*erf((ln(x) - center)/(sqrt(2)*sigma))
所以

应为您提供所需的分布。inverf是erf函数的逆函数。它是一个常用函数,但在math.h中不是

我做了一个基于SIMD的随机数发生器,需要进行分发。这个工作很好,假设我在打字时没有出错,上面的工作就可以了

根据要求,如何夹紧:

   //This is how I do it with my Random class where the first argument
   //is the min value and the second is the max 
   double CDF = Random::Range(0.0001,0.9999); //Depends on what you are using to random

   //How you get there from Random Ints
   unsigned int RandomNumber = rand();
    //Conver number to range [0,1]
   double CDF = (double)RandomNumber/(double)RAND_MAX; 
   //now clamp it to a min, max of your choosing
   CDF = CDF*(max - min) + min; 

你需要的是逆累积分布函数。这是一个函数,它是整个域上分布的归一化积分的倒数。因此,0%是你可能得到的最负的值,100%是你可能得到的最正的值。实际上,尽管你会平静到0.01%和99.99%之类的值否则,对于许多分布,您将以无穷大结束

然后,您只需要随机选择一个范围(0,1)内的数字,并将其插入函数。记住钳制它

double CDF = 0.5 + 0.5*erf((ln(x) - center)/(sqrt(2)*sigma))
所以

应为您提供所需的分布。inverf是erf函数的逆函数。它是一个常用函数,但在math.h中不是

我做了一个基于SIMD的随机数发生器,需要进行分发。这个工作很好,假设我在打字时没有出错,上面的工作就可以了

根据要求,如何夹紧:

   //This is how I do it with my Random class where the first argument
   //is the min value and the second is the max 
   double CDF = Random::Range(0.0001,0.9999); //Depends on what you are using to random

   //How you get there from Random Ints
   unsigned int RandomNumber = rand();
    //Conver number to range [0,1]
   double CDF = (double)RandomNumber/(double)RAND_MAX; 
   //now clamp it to a min, max of your choosing
   CDF = CDF*(max - min) + min; 

你需要的是逆累积分布函数。这是一个函数,它是整个域上分布的归一化积分的倒数。因此,0%是你可能得到的最负的值,100%是你可能得到的最正的值。实际上,尽管你会平静到0.01%和99.99%之类的值否则,对于许多分布,您将以无穷大结束

然后,您只需要随机选择一个范围(0,1)内的数字,并将其插入函数。记住钳制它

double CDF = 0.5 + 0.5*erf((ln(x) - center)/(sqrt(2)*sigma))
所以

应为您提供所需的分布。inverf是erf函数的逆函数。它是一个常用函数,但在math.h中不是

我做了一个基于SIMD的随机数发生器,需要进行分发。这个工作很好,假设我在打字时没有出错,上面的工作就可以了

根据要求,如何夹紧:

   //This is how I do it with my Random class where the first argument
   //is the min value and the second is the max 
   double CDF = Random::Range(0.0001,0.9999); //Depends on what you are using to random

   //How you get there from Random Ints
   unsigned int RandomNumber = rand();
    //Conver number to range [0,1]
   double CDF = (double)RandomNumber/(double)RAND_MAX; 
   //now clamp it to a min, max of your choosing
   CDF = CDF*(max - min) + min; 

你需要的是逆累积分布函数。这是一个函数,它是整个域上分布的归一化积分的倒数。因此,0%是你可能得到的最负的值,100%是你可能得到的最正的值。实际上,尽管你会平静到0.01%和99.99%之类的值否则,对于许多分布,您将以无穷大结束

然后,您只需要随机选择一个范围(0,1)内的数字,并将其插入函数。记住钳制它

double CDF = 0.5 + 0.5*erf((ln(x) - center)/(sqrt(2)*sigma))
所以

应为您提供所需的分布。inverf是erf函数的逆函数。它是一个常用函数,但在math.h中不是

我做了一个基于SIMD的随机数发生器,需要进行分发。这个工作很好,假设我在打字时没有出错,上面的工作就可以了

根据要求,如何夹紧:

   //This is how I do it with my Random class where the first argument
   //is the min value and the second is the max 
   double CDF = Random::Range(0.0001,0.9999); //Depends on what you are using to random

   //How you get there from Random Ints
   unsigned int RandomNumber = rand();
    //Conver number to range [0,1]
   double CDF = (double)RandomNumber/(double)RAND_MAX; 
   //now clamp it to a min, max of your choosing
   CDF = CDF*(max - min) + min; 

问题是我得到的数据集(1000个变量,值在79.5200和79.7120之间)的平均值(79.6137057)接近
平均值(81.2243980),但SD(15.6962440)非常不一致