楼主: fxf258
6924 22

请教如何判断一致性的问题 [推广有奖]

11
fxf258 发表于 2009-6-2 10:18:00

还是不明白,能否请高手们就此例问题作个分析。

嘉祥同志给的链接我看了,谢谢!也谢谢爱萌的指导!

海象

12
nkwilling 发表于 2009-6-2 10:32:00

楼主:直接按照嘉祥同志的指示,我等P民给你找了这段代码,你看看是不是你要的。

%macro magree(version, data=_last_, items=, raters=, response=, stat=BOTH ); %let _version=1.2; %if &version ne %then %put &sysmacroname macro Version &_version; %if &data=_last_ %then %let data=&syslast; %let opts = %sysfunc(getoption(notes)) _last_=%sysfunc(getoption(_last_)); %if &version ne debug %then %str(options nonotes;); /* Check for newer version */ %if %sysevalf(&sysver >= 7) %then %do; %let _notfound=0; filename _ver url 'http://ftp.sas.com/techsup/download/stat/versions.dat'; data _null_; infile _ver end=_eof; input name:$15. ver; if upcase(name)="&sysmacroname" then do; call symput("_newver",ver); stop; end; if _eof then call symput("_notfound",1); run; %if &syserr ne 0 or &_notfound=1 %then %put &sysmacroname: Unable to check for newer version; %else %if %sysevalf(&_newver > &_version) %then %do; %put &sysmacroname: A newer version of the &sysmacroname macro is available.; %put %str( ) You can get the newer version at this location:; %put %str( ) http://support.sas.com/ctx/samples/index.jsp; %end; %end; %let error=0; /* Verify DATA= is specified and the data set exists */ %if &data ne %then %do; %if %sysfunc(exist(&data)) ne 1 %then %do; %put ERROR: DATA= data set, %upcase(&data), not found.; %goto exit; %end; %end; %else %do; %put ERROR: The DATA= parameter is required.; %goto exit; %end; /* Verify required parameters were specified */ %if &items= %then %do; %put ERROR: The ITEMS= parameter is required.; %goto exit; %end; %if &raters= %then %do; %put ERROR: The RATERS= parameter is required.; %goto exit; %end; %if &response= %then %do; %put ERROR: The RESPONSE= parameter is required.; %goto exit; %end; %if %upcase(&stat) ne KAPPA and %upcase(&stat) ne KENDALL and %upcase(&stat) ne BOTH %then %do; %put ERROR: STAT= must be set to KAPPA, KENDALL, or BOTH.; %goto exit; %end; /* Check for existence of variable names */ %let dsid=%sysfunc(open(&data)); %if &dsid %then %do; %let chkitem=%sysfunc(varnum(&dsid,%upcase(&items))); %let chkrate=%sysfunc(varnum(&dsid,%upcase(&raters))); %let chkresp=%sysfunc(varnum(&dsid,%upcase(&response))); %let rc=%sysfunc(close(&dsid)); %end; %else %do; %put ERROR: Could not open DATA= data set.; %goto exit; %end; %if &chkitem=0 %then %do; %put ERROR: Variable %upcase(&items) not found.; %goto exit; %end; %if &chkrate=0 %then %do; %put ERROR: Variable %upcase(&raters) not found.; %goto exit; %end; %if &chkresp=0 %then %do; %put ERROR: Variable %upcase(&response) not found.; %goto exit; %end; title2 "The MAGREE macro"; /* Get type of response variable so can format later. ======================================================================*/ %let dsid=%sysfunc(open(&data)); %if &dsid %then %do; %let ynum=%sysfunc(varnum(&dsid,&response)); %let ytype=%sysfunc(vartype(&dsid,&ynum)); %let rc=%sysfunc(close(&dsid)); %end; %else %do; %put WARNING: Could not check type of &response variable.; %put %str( ) Continuing assuming it is numeric.; %end; /* Verify that all subjects have the same number of ratings. Note * that the raters variable must use the same values to identify the * raters in all subjects even if different raters rate the subjects. * But the number of raters must be the same across all subjects. * Create response by item summary table needed to compute kappas and * get numbers of subjects, raters, and response categories. ======================================================================*/ data _nomiss; set &data; if &response ne " "; run; proc freq data=_nomiss noprint; table &items*&raters / sparse out=_balance; table &response*&items / out=_ycnts(drop=percent); table &items / out=_n; table &raters / out=_m; table &response / out=_k(drop=count percent); run; data _null_; set _balance nobs=_nobs; if count ne 1 then call symput('error',1); run; %if &error %then %do; %put ERROR: Each rater must rate each subject exactly once.; %goto exit; %end; data _null_; set _n nobs=n; set _m nobs=m; set _k nobs=k; call symput('m',left(m)); call symput('n',left(n)); call symput('k',left(k)); run; %if &m=1 or &n=1 %then %do; %put ERROR: There must be more than one rater and more than one subject.; %goto exit; %end; /************************ Compute kappa ******************************/ %if %upcase(&stat)=KAPPA or %upcase(&stat)=BOTH %then %do; /* Create coded values (1,2,3,...) for response categories to use as * indices. ======================================================================*/ data _ycnts; set _ycnts; by &response; if first.&response then _code+1; run; /* Compute kappa statistics for each category and overall ======================================================================*/ data _kappas; set _ycnts end=eof; array kapnum {&k} knum1-knum&k; array catsum {&k} sum1-sum&k; array kapj {&k} kappa1-kappa&k; /* V6 limit: 999 categories */ array pb {&k} pbar1-pbar&k; array zkapj {&k} zkj1-zkj&k; array prkapj {&k} prkj1-prkj&k; kapnum{_code} + count*(&m - count); catsum{_code} + count; if eof then do; knum=0; kden=0; pqqp=0; nmm = &n*&m*(&m-1); sekapj=sqrt(2/nmm); do j=1 to &k; pb{j} = catsum{j}/(&m*&n); pq = pb{j}*(1-pb{j}); if pq<1e-8 then kapj{j}=1; else kapj{j} = 1 - (kapnum{j}/(nmm*pq)); zkapj{j} = kapj{j}/sekapj; prkapj{j} = 1-probnorm(zkapj{j}); knum = knum + pq*kapj{j}; kden = kden + pq; pqqp = pqqp + pq*((1-pb{j})-pb{j}); end; if kden<1e-8 then do; kappa=1; sekap=.; end; else do; kappa=knum/kden; sekap = (sqrt(2)/(kden*sqrt(nmm)))*sqrt(kden**2-pqqp); end; zkap=kappa/sekap; prkap=1-probnorm(zkap); keep &response kapp stderr z prob; do i=1 to &k; set _k; kapp=kapj{i}; stderr=sekapj; z=zkapj{i}; prob=prkapj{i}; output; end; &response=.; kapp=kappa; stderr=sekap; z=zkap; prob=prkap; output; end; run; /* Print kappa statistics ======================================================================*/ %let fexist=0; data _null_; if ("&ytype"="N" and cexist("work.formats._yfmt.format") ne 1) or ("&ytype"="C" and cexist("work.formats._yfmt.formatc") ne 1) then call symput("fexist","1"); run; %if &fexist %then %do; proc format; value %if &ytype=C %then $_yfmt; %else _yfmt; .="Overall"; run; %end; proc print noobs label; format prob pvalue. &response %if &ytype=C %then $_yfmt.; %else _yfmt.; ; label kapp="Kappa" stderr="Standard Error" prob="Prob>Z"; title3 "Kappa statistics for nominal response"; run; %end; /*********** Compute Kendall's Coefficient of Concordance, W ***********/ %if %upcase(&stat)=KENDALL or %upcase(&stat)=BOTH %then %do; %if &ytype=C %then %do; %put %str(ERROR: Kendall%'s Coefficient of Concordance requires a numeric, ordinal response.); %goto exit; %end; /* Rank the data using average ties. If data are already ranked, this * won't change anything. ======================================================================*/ proc sort data=&data out=_sortr; by &raters; run; proc rank data=_sortr out=_ranked; by &raters; var &response; run; /* R-square from one-way ANOVA is Kendall's W. ======================================================================*/ proc anova data=_ranked outstat=_anova noprint; class &items; model &response = &items; run; /* Compute F statistic and p-value for testing W=0. Ties are handled correctly. ======================================================================*/ data _w; set _anova; retain SSsubj; if _n_=2 then do; numdf=&n-1-2/&m; dendf=(&m-1)*numdf; if ss=0 and SSsubj=0 then do; w=1; f=.; prob=.; end; else do; w=ss/(ss+SSsubj); if w=1 then do; f=.I; prob=0; end; else do; f=(&m-1)*w/(1-w); prob=1-probf(f,numdf,dendf); end; end; keep w f numdf dendf prob; output; end; SSsubj=ss; run; /* Print Kendall's coefficient of concordance and test ======================================================================*/ proc format; value _fval .i='Infty'; run; proc print noobs label; var w f numdf dendf prob; format prob pvalue. f _fval.; label w="Coeff of Concordance" numdf="Num DF" dendf="Denom DF" prob="Prob>F"; title3 "Kendall's Coefficient of Concordance for ordinal response"; run; %end; %exit: options &opts; title; %mend magree; 

13
fxf258 发表于 2009-6-2 10:51:00
谢谢nkwilling的热心帮助!我也看了嘉祥提供链接的一个例子,我英文不好,好像也不太符合我提出的问题?我再看看,谢谢各位
海象

14
nkwilling 发表于 2009-6-2 12:58:00
爱萌版主你要是会,直接给人家解决不就行了?给现成的答案比什么指导意见要好得多,人家要是不懂,你给指导意见不是等于没给吗?

15
realgod5417 发表于 2009-6-2 13:35:00

To 楼主,根据2楼,8楼,12楼各位高手的介绍,总结结果解释,过程如下,

首先分析一下你的数据,你的评定者(rater)有7个人,对同一个个体做7个项目(item)的检测,你要说明7个评定者之间对7个项目的评定是否一致?这里提一下你的7个指标是得到的值是ordinal的还是nominal,如果是ordinal的结果用Kendall's statistic 如果是nominal的用kappa(我是这样理解的,如果同意继续忘下看,如果不同意下面多就不用看了)

那么假设一致性很好,对于每个小的项目来说7个人的结果就应当是相同的,因此你可以这样考虑,你的7个项目item相当于做了7个subject,7个rater对7个subject的评定是否一致.

那么你可以先用2楼的方式把数据写入,这里注意一下和2楼有点不一样你的row是rater而column是不同项目;


data raw;
do rater=1 to 7;
do item=1 to 7;
input score @@;
output;
end;
end;
cards;
2 2 3 3 2 2 2
1 2 3 3 3 2 3
1 2 3 3 2 3 2
2 3 2 2 2 3 2
1 2 3 2 3 2 3
2 2 3 3 2 2 3
2 2 3 3 2 2 3
;
run;

然后你把8楼给的连接,也就是11楼版主贴上的程序粘贴下来

最后加上下面程序即可,

 %magree(data=raw,
              items=item,
              raters=rater,
              response=score)

得到结果如下

                                        The MAGREE macro
                              Kappa statistics for nominal response

                                             Standard
                        score      Kappa       Error        z       Prob>Z

                             1    0.28986    0.082479    3.51431    0.0002
                             2    0.09866    0.082479    1.19622    0.1158
                             3    0.23966    0.082479    2.90566    0.0018
                       Overall    0.18085    0.070719    2.55732    0.0053

                                                                 12:37 Wednesday, June 2, 2009  12
                                         The MAGREE macro
                    Kendall's Coefficient of Concordance for ordinal response

                         Coeff of                          Denom
                       Concordance      F       Num DF       DF      Prob>F

                         0.42276      4.394    5.71429    34.2857    0.0024

梅须逊雪三分白雪却输梅一段香

16
fxf258 发表于 2009-6-2 17:20:00

realgod5417的总结非常到位,目前就是要解决这个问题,根据realgod5417的解答,运行成功,那么如何解释上面的结果呢?如果数据是ordinal如何解释?如果数据是nominal又该如何解释?还望赐教!

另外:如果受试者是2位或3位,同样研究者是7位,又该如何评判其一致性呢?

非常感谢各位的解答!

海象

17
爱萌 发表于 2009-6-2 18:59:00

zealous, happy

最恨对我说谎或欺骗我的人

18
rdzr 发表于 2009-6-3 09:51:00

各位高人、牛人、达人:

看了众高手所给出的答案,偶深感受益匪浅,但同时又觉得可能有些问题是不是有值得商榷的地方,比如:

1、一谈到“一致性”是不是就是指要求出kappa 系数;

2、共有7名研究者对1名受试者7个项目进行测试,但我们是否可以从另一角度换位思考:即可否借鉴调查问卷的方法,把这一问题理解为“7名被调查者分别回答同样的7个问题”,现在所要做的就是分析一个这7个人对相同问题的回答是否有显著的不同

如果 上述两个问题,特别是第2个问题成立的话,那么 我们就可以用采用 Friedman 检验 来回答 LZ 的问题。参考程序如下:

data raw;
do name=1 to 7;
do evaluator=1 to 7;
input score @@;
output;
end;
end;
cards;
2 2 3 3 2 2 2
1 2 3 3 3 2 3
1 2 3 3 2 3 2
2 3 2 2 2 3 2
1 2 3 2 3 2 3
2 2 3 3 2 2 3
2 2 3 3 2 2 3
;
run;

proc freq;

 tables evaluator*name*score/scores=rank cmh2;/*Friedman检验可用 freq 过程实现*/

run;

运行结果如下:

                The SAS System          09:42 Thursday, June 3, 2009   8

                                       The FREQ Procedure

                              Summary Statistics for name by score
                                    Controlling for evaluator

                    Cochran-Mantel-Haenszel Statistics (Based on Rank Scores)

                 Statistic    Alternative Hypothesis    DF       Value      Prob
                 ---------------------------------------------------------------
                     1        Nonzero Correlation        1      0.2045    0.6511
                     2        Row Mean Scores Differ     6      1.0909    0.9819


                                     Total Sample Size = 49

由于 第2个 cmh统计量为1.0909,对应的 P—Value 为 0.9819 ,所以可以认为这7个人对同一受试者7个问题的测试结果是高度一致的!

(以上意见 仅供参考,谢谢!)

19
fxf258 发表于 2009-6-3 11:30:00

谢谢rdzr的建议!换位思考的建议很好,我个人认为这样是可行的,实际上这个问题就相当于一个调查问卷的分析。如果这种理解正确的话,realgod5417的Kappa分析和Rdzr的Friedman分析结论不一致,是什么原因造成的呢?

还请各位高手继续讨论,谢谢!

海象

20
fxf258 发表于 2009-6-4 09:27:00

请教高人,realgod5417的Kappa分析和Rdzr的Friedman分析结论不一致,该如何处理呢?

期待中,谢谢!

海象

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-1 08:10