我在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) -->?
答案 0 :(得分:3)
您需要的内容记录在各个地方,例如:
http://www.stata.com/support/faqs/statistics/percentile-ranks-and-plotting-positions/
http://www.stata-journal.com/sjpdf.html?articlenum=gr0027
就您的代码而言:
(统计)在排名之前标准化变量没有坏处但是非常不必要,因为标准化变量的等级与变量本身的等级相同。
(Stata)通常也不需要在变量中(即在数据集的每个观察或行中)设置常量。
(统计)您应该按值的数量来衡量排名,而不是最大等级。如果多个值最大值匹配,则观察到的最高等级将小于值的数量。 (玩具示例:5个值1,2,3,3,3将排名1,2,4,4,4,因此最高等级为4,而不是5.)
(?)我无法理解您要对该行replace max = 0.5/max
(Stata)没有函数qnorm()
;你想要的那个被称为invnormal()
,正如help functions
会告诉你的那样。
我认为你想要的是
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
变量month
,sector
等是可选的(即bysort month sector:
是可选的,以供您在想要按群组执行操作时使用)