做systematic review, 有三个rater评价一篇文章是否纳入研究,假设一共有4000篇文章
rater1 78 篇需要纳入 3922 排除
rater2 160 纳入 3840排除
rater3 112 纳入 3888排除
如何用SAS计算这三个rater间的一致性呢?
看到论坛上有一篇类似求助, 但是大佬提供的code没看懂该怎么代入以上情况,求解释,多谢多谢!
https://bbs.pinggu.org/thread-2252667-1-1.html
%MACRO KAPPA(dataset=,vars_rater=);
%local dataset vars_rater label n_rater1 n_rater2 i j id;
%let n_raters=%sysfunc(countw("&vars_rater."));
data kappa_t1(keep=subj ranking) ; /*Transform dataset structure*/
set &dataset.(KEEP=&vars_rater.);
subj=_n_;
%do i=1 %to %sysfunc(countw("&vars_rater."));
rater=&i.;
ranking=%scan(&vars_rater.,&i.);
output;
%end;
run;
proc freq data=kappa_t1 noprint;
table subj*ranking/out=kappa_t2(keep=subj ranking count);
run;
proc sql NOPRINT;
select count(distinct subj),count(distinct ranking) into :n_subjs,:n_rankings
from kappa_t2;
create table kappa_t3
as select distinct subj
from kappa_t2
where subj is not null
order by subj;
create table kappa_t4
as select distinct ranking
from kappa_t2
where ranking is not null
order by ranking;
create table kappa_t5
as select *
from kappa_t3,kappa_t4
order by subj,ranking;
proc sort data=kappa_t2;by subj ranking;run;
data kappa_t6;
merge kappa_t2 kappa_t5(in=a);
by subj ranking;
if a;
RUN;
data kappa_t6;
set kappa_t6;
if count=. then count=0;
xmx=count*(&n_raters.-count);
run;
proc sort data=kappa_t6;
by ranking;
run;
data kappa_t6(keep=ranking x xmx2);
set kappa_t6;
by ranking;
retain x xmx2;
if first.ranking then do; x=0; xmx2=0; end;
x=x+count; xmx2=xmx2+xmx;
if last.ranking then output;
run;
data kappa_t6;
set kappa_t6;
p=x/(&n_subjs.*&n_raters.);
pq=p*(1-P);
pqp=p*(1-p)*(1-2*p);
kj=abs(1 - xmx2/(&n_subjs.*&n_raters.*(&n_raters.-1)*pq));
numj=kj*pq;
run;
data kappa_t6;
set kappa_t6;
if p=0 then do;
kj=0; numj=0;
end;
run;
data kappa_t7;
set kappa_t6 end=end;
retain num den pqpsum;
if _n_=1 then do;
num=0; den=0; pqpsum=0;
end;
num=num+numj;
den=den+pq;
pqpsum=pqpsum+pqp;
if end then output;
run;
data kappa_t8; set kappa_t7;
keep Kappa SE CI pvalue;
Kappa=num/den;
SE=sqrt(2*(den*den-pqpsum))/(den*sqrt(&n_subjs.*&n_raters.*(&n_raters.-1)));
ci=cats(put(kappa-1.96*se,8.3),"~",put(kappa+1.96*se,8.3));
pvalue=1-probnorm(kappa/se);
run;
proc print data=kappa_t8 noobs label;
label kappa="Overall Kappa" SE="Standard Error" ci="95% CI" pvalue="Prob>Z";
title "Kappa statistics for &N_rankings.-category ratings by &N_raters raters";
run;
/*---------------------------------------Calculate inner 2 raters kappa----------------------------------*/
%let start=1;%let id=1;
%do i=&start. %to %eval(&n_raters.-1);
%do j=%eval(&i.+1) %to &n_raters.;
%let rater1=%scan(&vars_rater.,&i.);
%let rater2=%scan(&vars_rater.,&j.);
data kappa_temp1 kappa_temp2 kappa_temp3 kappa_temp4 kappa_temp5 kappa_temp6;run;
data kappa_temp1;
set &dataset.(keep=&rater1. &rater2.);
retain weight 1;
run;
proc tabulate data=kappa_temp1;
class &rater1. &rater2.;
table &rater1.="" all="ALL",(&rater2. all="ALL")*n=""/box="&rater1." MISSTEXT="0";
title "distribution of &rater1. and &rater2.";
run;
proc sql NOPRINT;
select count(distinct &rater1.) into :n_rater1
from kappa_temp1
where &rater1. is not null;
select count(distinct &rater2.) into :n_rater2
from kappa_temp1
where &rater2. is not null;
create table kappa_temp2
as select distinct &rater1.
from kappa_temp1
where &rater1. is not null
union
select distinct &rater2. as &rater1.
from kappa_temp1
where &rater2. is not null;
quit;
data kappa_temp3;
set kappa_temp2;
rename &rater1.=&rater2.;
run;
proc sql NOPRINT;
create table kappa_temp4
as select *
from kappa_temp2,kappa_temp3;
quit;
data kappa_temp4;
set kappa_temp4;
retain weight 0;
run;
proc sql NOPRINT;
create table kappa_temp5
as select &rater1.,&rater2.,weight
from kappa_temp1
union all
select &rater1.,&rater2.,weight
from kappa_temp4
where sum(kappa_temp4.&rater1.*100,kappa_temp4.&rater2.) not in
(select sum(kappa_temp1.&rater1.*100,kappa_temp1.&rater2.) from kappa_temp1);
quit;
proc freq data=kappa_temp5 noprint; /*Kappa Statistics*/
table &rater1.*&rater2./agree;
test kappa WTKAP;
weight weight/zero;
output out=kappa_temp6 agree;
run;
%if &n_rater1.=2 and &n_rater2.=2 %then %do; /*Prepare for report*/
data kappa_temp6(keep=name stat se ci stat3 p1 p2);
set kappa_temp6;
length name 18stat8SE8CI18stat8SE8CI 18 stat 8 SE 8 CI 16 stat 8 stat 8 p1 8 p2 8;
retain raters "&rater1. - &rater2.";
name="McNemarS";Stat=_mcnem_;P2=p_mcnem;output;
name="";stat=.;se=.;ci="";stat2=.;stat3=.;p1=.;p2=.;
name="简单Kappa系数";Stat=_KAPPA_;SE=E_KAPPA;
CI=cats(put(l_kappa,8.3),"~",put(U_KAPPA,8.3));stat2="Kappa=0检验"; stat3=z_KAPPA;
P1=mean(PR_KAPPA,PL_KAPPA);P2=P2_KAPPA;output;
label name="统计方法" stat="统计量" SE="标准误" CI="95% CI" stat2="检验" stat3="Z值" P1="单侧P值" P2="双侧P值";
run;
data kappa_temp6;
length id 8 raters $ 24;
set kappa_temp6;
n=_n_;
if n=1 then do;
id=%eval(&id.);
raters="&rater1. - &rater2.";
end;
drop n;
run;
%end;
%else %do;
data kappa_temp6(keep= name stat se ci stat3 p1 p2);
set kappa_temp6;
length name 18stat8SE8CI18stat8SE8CI 18 stat 8 SE 8 CI 16 stat 8 stat 8 p1 8 p2 8;
retain raters "&rater1. - &rater2.";
name="对称性检验S";Stat=_tsymm_;P2=p_tsymm;output;
name="";stat=.;se=.;ci="";stat2=.;stat3=.;p1=.;p2=.;
name="简单Kappa系数";Stat=_KAPPA_;SE=E_KAPPA;
CI=cats(put(l_kappa,8.3),"~",put(U_KAPPA,8.3));stat2="Kappa=0检验"; stat3=z_KAPPA;
P1=mean(PR_KAPPA,PL_KAPPA);P2=P2_KAPPA;output;
name="";stat=.;se=.;ci="";stat2=.;stat3=.;p1=.;p2=.;
name="加权Kappa系数";Stat=put(_wtkap_,8.3);SE=put(E_wtkap,8.3);
CI=cats(put(l_wtkap,8.3),"~",put(U_wtkap,8.3));stat2="加权Kappa=0检验"; stat3=z_wtkap;
P1=mean(PR_wtkap,PL_wtkap);P2=P2_wtkap;output;
label name="统计方法" stat="统计量" SE="标准误" CI="95% CI" stat2="检验" stat3="Z值" P1="单侧P值" P2="双侧P值";
run;
data kappa_temp6;
length id 8 raters $ 24;
set kappa_temp6;
n=_n_;
if n=1 then do;
id=%eval(&id.);
raters="&rater1. - &rater2.";
end;
drop n;
run;
%end;
%if &i.=1 and &j.=2 %then %do;
data kappa_temp7;
set kappa_temp6;
run;
%end;
%else %do;;
data kappa_temp7;
set kappa_temp7 kappa_temp6;
run;
%end;
%let id=%eval(&id.+1);
%end;
%let start=%eval(&start.+1);
%end;
proc sql;
create table kappa_temp8
as select avg(stat) as stat,avg(se) as se,"平均的简单Kappa系数" as name
from kappa_temp7
where name="简单Kappa系数"
union
select avg(stat) as stat,avg(se) as se,"平均的加权Kappa系数" as name
from kappa_temp7
where name="加权Kappa系数";
data kappa_temp8;
length raters $ 24;
set kappa_temp8;
id=0;
raters="All";
run;
data kappa_temp8;
set kappa_temp8 kappa_temp7;
run;
proc print data=kappa_temp8 label noobs; /*Report Kappa Statistics*/
title "Kappa Statistics ";
var id raters name stat SE CI stat3 p1 p2 ;
run;
proc datasets nolist ;
delete kappa_: k_temp:;
run;quit;
%MEND;
%KAPPA(dataset=k_temp3,vars_rater=rater1 rater2 rater3 );