如何使用Stata(来自R)进行基于秩的逆正态变换

时间:2013-12-13 18:01:50

标签: r transformation stata

我在R(rntransform {GenABEL})中有这个函数,它对一个变量进行反正态rankBased变换,并希望在Stata中做同样的事情。但是,我似乎无法破译最后一步(qnorm(out)):

function (formula, data, family = gaussian) 
{
    if (is(try(formula, silent = TRUE), "try-error")) {
        if (is(data, "gwaa.data")) 
            data1 <- phdata(data)
        else if (is(data, "data.frame")) 
            data1 <- data
        else stop("'data' must have 'gwaa.data' or 'data.frame' class")
        formula <- data1[[as(match.call()[["formula"]], "character")]]
    }
    var <- ztransform(formula, data, family)
    out <- rank(var) - 0.5
    out[is.na(var)] <- NA
    mP <- 0.5/max(out, na.rm = T)
    out <- out/(max(out, na.rm = T) + 0.5)
    out <- qnorm(out)
    out
}

有人知道如何在Stata中执行此操作吗?

应该是

  egen stdVar = std(Var)
  egen stdVar_rank=rank(stdVar)-0.5
  egen max= max(stdVar_rank)
  replace max = 0.5/max
  replace  stdVar_rank= stdVar_rank/max
  gen InvRankNormVar =  qnorm(stdVar_rank) -->?

2 个答案:

答案 0 :(得分:3)

您需要的内容记录在各个地方,例如:

http://www.stata.com/support/faqs/statistics/percentile-ranks-and-plotting-positions/

http://www.stata-journal.com/sjpdf.html?articlenum=gr0027

就您的代码而言:

  1. (统计)在排名之前标准化变量没有坏处但是非常不必要,因为标准化变量的等级与变量本身的等级相同。

  2. (Stata)通常也不需要在变量中(即在数据集的每个观察或行中)设置常量。

  3. (统计)您应该按值的数量来衡量排名,而不是最大等级。如果多个值最大值匹配,则观察到的最高等级将小于值的数量。 (玩具示例:5个值1,2,3,3,3将排名1,2,4,4,4,因此最高等级为4,而不是5.)

  4. (?)我无法理解您要对该行replace max = 0.5/max

  5. 所做的事情
  6. (Stata)没有函数qnorm();你想要的那个被称为invnormal(),正如help functions会告诉你的那样。

  7. 我认为你想要的是

    egen rank = rank(Var)
    su Var, meanonly 
    gen InvRankNormVar = invnormal((rank - 0.5) / r(N)) 
    

    r(N)之后可以立即访问summarize的非缺失值的数量。

    P.S。我没有尝试阅读你的R代码。我只是作为R初学者才有资格。

答案 1 :(得分:2)

如果您想再次使用此计算,请尝试此ado代码(相当于Stata中的R函数)。将ado文件保留在C:/ado/personal/_/_gnormalize.ado(或您个人ado文件的任何位置):

program define _gnormalize
    version 9.2
**************************************[ NORMALIZE ]********************************
* 
* This function converts a raw factor into normalized Z-Score
*   option `1' is the raw factor
*   option `2' is additional grouping, e.g. sector
*
**************************************[ NORMALIZE ]*******************************

    gettoken type 0 : 0
    gettoken g    0 : 0
    gettoken egs 0 : 0
    syntax varlist(min=1) [, BY(string)]

    if `"`by'"'!="" {
        local by `"by `by':"'
    }

    quietly {
        gen `type' `g' = .
        `by' egen `g'rank = rank(`varlist'), unique
        `by' egen `g'count = count(`varlist') if `varlist'~=.
        replace `g'=invnormal((`g'rank-0.5)/`g'count) if `varlist'~=.
        drop `g'rank `g'count
    }
end

用法如下:

bysort month sector: egen my_transscore = normalize(my_factor)

其中by变量monthsector等是可选的(即bysort month sector:是可选的,以供您在想要按群组执行操作时使用)