1 ' 2-WAY ANOVA, UNREPLICATED -- ANOVU.BAS -- by Dr Russell Langley
2 GOTO 400
4 '<UNK! {000A}>--- Press Enter ---
5 IF PR THEN RETURN ELSE PRINT TAB(40);:PRINT "Press <Enter> to continue.";:IN$=INKEY$:WHILE INKEY$<>CHR$(13):WEND:LOCATE,40:PRINT SPACE$(26):RETURN
6 PRINT TAB(14);:PRINT "Press <Enter> to continue, or `/' to end viewing.";:IN$=INKEY$:WHILE IN$<>CHR$(13) AND IN$<>"/":IN$=INKEY$:WEND:LOCATE,14:PRINT SPACE$(50):IF IN$="/" THEN I=N:RETURN ELSE RETURN
7 '<UNK! {000A}>*** Redirect to Block ***
9 ON QB GOTO 2,177,10,30:STOP '=start,printout,re-run,quit.<UNK! {000A}><UNK! {000A}>*** Another go? ***
10 CLOSE:IF QB<>3 THEN IF HEAD=1 THEN LPRINT CHR$(10)STRING$(79,61)STRING$(4,10)
11 DO$="run this program again now":GOSUB 20:IF Z$="Y" THEN 2 ELSE 30
19 '<UNK! {000A}>--- Yes/No? ---
20 PRINT:PRINT"Do you want to "+DO$;
21 INPUT" (Y/N)";Z$:IF Z$="" THEN Z$="N":RETURN ELSE Z$=CHR$(ASC(Z$) AND 95):IF Z$="Y" OR Z$="N" THEN RETURN ELSE PRINT"WHAT? ";:GOTO 21
29 '<UNK! {000A}>--- Errors & End ---
30 IF ERR THEN BEEP ELSE RUN "MENU"
31 IF ERR=70 THEN LINE INPUT"Can't write to that disk. Remove its Write-Protect tab, then press <Enter>.";Z$:RESUME
32 IF ERR=71 THEN LINE INPUT"That drive is empty or its gate is open. Fix, then press <Enter>.";Z$:RESUME
33 IF ERR=210 THEN RESUME 9 'from #86
39 ON ERROR GOTO 0:END'<UNK! {000A}><UNK! {000A}>--- Messages ---
40 BEEP:PRINT "---> Sorry, that entry is illegal.":RETURN
41 BEEP:PRINT "---> Sorry, double quotes are not allowed here.":RETURN
42 BEEP:PRINT"* * * Can't Do That.":QB=4:GOTO 9
43 COLOR 23,0:PRINT:PRINT"Working";:COLOR 7,0:RETURN
44 LOCATE,1:PRINT"Ok, done.";:GOTO 5
49 '<UNK! {000A}>--- Vetted Decoding of FF X(I,J) from X$ ---<UNK! {000A}> Needs I, M, Q(0) from #96 or #256, & UT>0 if UT matrix.
50 K=1:L=M
51 KX=0:FOR J=K TO L:Y$=SPACE$(10):KY=0
52 KX=KX+1:IF KX>LEN(X$) THEN IF J=L THEN 54 ELSE 57
53 Z$=MID$(X$,KX,1):IF INSTR("-.0123456789",Z$) THEN KY=KY+1:MID$(Y$,KY,1)=Z$:GOTO 52 ELSE IF Z$<>" " THEN 58 ELSE IF KY=0 THEN 52
54 IF Q(0) THEN Q(J)=VAL(Y$) ELSE X(I,J)=VAL(Y$)
55 NEXT J:IF KX>=LEN(X$) THEN 60
56 PLAY"L8O3CO2C":PRINT"Only the first"L"values have been read in that line. Re-do it";:GOSUB 21:IF Z$="Y" THEN 59 ELSE 60
57 PLAY"L32O4CEG>C":PRINT"Not enough values in the line above. Please re-do whole line.":GOTO 59
58 PLAY"L16O3CEL4>B":PRINT"That line contains a `non-numeric' entry. Please re-do whole line."
59 IF Q(0)=1 THEN 61 ELSE PRINT"Row"STR$(I);:INPUT X$:IF RIGHT$(X$,1)<>"/" THEN 51 ELSE X$=LEFT$(X$,LEN(X$)-1):N=I+(X$=""):IF X$>"" THEN 51
60 RETURN
61 INPUT X$:IF X$="" THEN 61 ELSE 51
69 '<UNK! {000A}>--- K/b Input of all X(I,J) in FF ---<UNK! {000A}> Needs first I, M, Q>0 (sample #), KN(Q), & if UT matrix UT>0. Returns N.
70 PRINT"Enter data from keyboard, ";:IF M=1 THEN PRINT "pressing <Enter> after each number.":GOTO 72
71 PRINT"in Free Format, pressing <Enter> at end of each row.":IF UT THEN 73
72 PRINT"Null entry duplicates previous row. Signal `end-of-data' by entering a `/'"
73 PRINT "Row"STR$(I);:INPUT X$:IF UT>0 AND I=M THEN N=M:GOTO 75 ELSE IF X$=""THEN IF I>1 THEN FOR J=1 TO M:X(I,J)=X(I-1,J):NEXT J:I=I+1:LOCATE CSRLIN-1,POS(0)+9:PRINT"Ditto":GOTO 73
74 IF RIGHT$(X$,1)="/" THEN X$=LEFT$(X$,LEN(X$)-1):N=I+(X$=""):IF X$="" THEN 76
75 GOSUB 50:IF N=0 THEN IF I<MXR THEN I=I+1:GOTO 73 ELSE N=MXR
76 RETURN
79 '<UNK! {000A}>*** Disk Input of X(I,J), N, M, etc ***<UNK! {000A}> Needs MNR, MNC, & NEEDVARS.
80 QD=1:IO$="I":GOSUB 110:CLS:PRINT "Loading data from disk.":INPUT #1,FL$,VR$
81 IF LEFT$(VR$,4)<>"(RL," THEN BEEP:PRINT "Unreadable file --- not made by our Data Filer/Editor program.":GOTO 86
83 IF UT>0 THEN PRINT "This file is an upper triangular matrix, which this program can't use!":GOTO 86
84 PRINT"File has"N"rows of data. ";:IF N<MNR THEN PRINT "--- Not enough!":GOTO 86 ELSE IF N>MXR THEN PRINT"--- Too many!":GOTO 86
85 PRINT:PRINT"File has"M"column variables. ";:IF M<MNC THEN PRINT "--- Not enough!" ELSE IF M>MXC THEN PRINT"Too many!" ELSE 88
86 CLOSE:BEEP:GOSUB 5:ERROR 210
87 A=M:B=N:GOSUB 433 ' set dimensions<UNK! {000A}><UNK! {000A}>---Select variables
88 PRINT:IF VN$="N" THEN PRINT "The"M"variables are not named.":GOTO 90
89 PRINT "Variables in file are:":FOR J=1 TO M:INPUT #1,VN$(J):PRINT J;VN$(J),:NEXT J:PRINT
90 IF M=MNC OR UT>0 THEN 100 ELSE PRINT
91 IF NEEDVARS=0 THEN PRINT"How many filed column variables are to be IGNORED (0-"MID$(STR$(M-MNC),2)")";:INPUT ND:IF ND<0 OR ND>M-MNC THEN 91 ELSE IF ND=0 THEN 100
92 '
93 '
94 IF ND=1 THEN PRINT "Number of the variable to be IGNORED (1-"MID$(STR$(M),2)")";:INPUT X$:Q(1)=VAL(X$):IF Q(1)<1 OR Q(1)>M THEN GOSUB 40:GOTO 94 ELSE 97
95 PRINT MID$(STR$(ND),2)" numbers of variables to be IGNORED (in ascending order & Free Format):":INPUT X$:IF VAL(X$)<1 THEN GOSUB 40:GOTO 95
96 Q(0)=1:MM=M:M=ND:GOSUB 50:Q(0)=0:M=MM
97 KK=1:L=1:FOR J=1 TO M:IF J=Q(KK) THEN KK=KK+1 ELSE VN$(L)=VN$(J):L=L+1
98 NEXT J
99 ' Now read numerical data from disk
100 COLOR 23,0:PRINT"Loading numbers";:COLOR 7,0:FOR I=1 TO N:KK=1:LL=1:L=M
101 FOR J=1 TO L:INPUT #1,Z
102 IF J=Q(KK) THEN KK=KK+1 ELSE X(I,LL)=Z:LL=LL+1
103 NEXT J:NEXT I:CLOSE:LOCATE,1:M=M-ND:RETURN
109 '<UNK! {000A}>--- Get Filespec ---
110 IF IO$="O" THEN STOP
111 LINE INPUT "Filename (I will add .DAT extension)? ";FL$:IF FL$="" THEN 111 ELSE IF MID$(FL$,2,1)=":" THEN DR$=LEFT$(FL$,1):FL$=MID$(FL$,3)
112 ER=0:FOR I=1 TO LEN(FL$):Z$=MID$(FL$,I,1):IF INSTR(" .,/\|?*:;[]+="+CHR$(34),Z$) THEN ER=1
113 NEXT I
114 IF ER=0 AND FL$>"" AND LEN(FL$)<9 THEN FL$=FL$+".DAT" ELSE BEEP:PRINT "Invalid filename. Will you try again";:GOSUB 21:IF Z$="Y" THEN 111 ELSE 2
115 INPUT "Which drive (A,B,C,D)";DR$:IF DR$="" THEN 115
116 DR$=CHR$(ASC(DR$) AND 95):IF INSTR("ABCD",DR$)=0 THEN 115
117 INPUT "Which directory (e.g. WORK, MYDATA, or Null Entry if root) ";DR2$:IF DR2$="" THEN DR$=DR$+":" ELSE DR$=DR$+":\"+DR2$+"\"
129 '<UNK! {000A}>--- Open File, IO$= "I" or "O" ---
130 IF IO$="I" THEN 134 ELSE STOP
131 '
132 '
133 '
134 ON ERROR GOTO 136:OPEN DR$+FL$ FOR INPUT AS #1 'for input
430 QD=0:INPUT "No. of Rows (2-20) ";X$:B=VAL(X$):IF B<2 OR B>MXR THEN 430
431 INPUT "No. of Columns (2-10) ";X$:A=VAL(X$):IF A<2 OR A>MXC THEN 431
432 DIM X(B,A)
433 DIM N(B),A(A),AM(A),B(B),BM(B),GR(A),SM(A),S(A),R(A),AL(A),BE(B),TU(B),D(A,A),C(A,A),IP(A),P(A),KR(A),KC(A),CM(A-1):IF QD=1 THEN RETURN
434 PRINT"Enter measurements by rows, in Free Format ---":M=A:I=1
435 PRINT"Row"I;:INPUT X$:IF X$="" THEN 435 ELSE GOSUB 50:IF I<B THEN I=I+1:GOTO 435
436 CLS:PRINT"Data read was:":M=A:FOR I=1 TO B:GOSUB 200:NEXT I:GOSUB 5
437 '<UNK! {000A}>--- Edit ---
438 INPUT "Edit (C#=Change row, SA=Show all, Null=Proceed) ";Z$
439 IF Z$="" THEN 445 ELSE IF Z$="SA" OR Z$="sa" THEN 436
440 LZ$=LEFT$(Z$,1):IF LZ$="C" OR LZ$="c" THEN J=VAL(MID$(Z$,2)):IF J>0 AND J<=B THEN 442
441 PRINT"Sorry. Try again.":GOTO 438
442 PRINT"For row "MID$(STR$(J),2)", enter VARIABLE # (1-"MID$(STR$(A),2)") & new VALUE (Free Format) ";:INPUT X$:IF X$="" THEN 442 ELSE Q=J:I=J:Q(0)=1:M=2:GOSUB 50:J=Q:Q(0)=0:M=A
443 IF Q(1)<1 OR Q(1)>A THEN 441 ELSE X(J,Q(1))=Q(2):PRINT"Row"J"now =";:FOR I=1 TO A:PRINT X(J,I);:NEXT I:PRINT:GOTO 438
444 '<UNK! {000A}>--- Print Data? ---
445 DO$="print data":GOSUB 20:IF Z$="N" THEN 448 ELSE GOSUB 162:GOSUB 165:IF VN$<>"Y" THEN PRINT #2,"Columns are not named." ELSE FOR I=1 TO A:PRINT #2,"Col"I"= "VN$(I)" ";:NEXT I:PRINT #2,
446 PRINT #2,:PRINT #2,"Data used:":FOR J=1 TO B:PRINT #2,USING "Row##: ";J;:FOR I=1 TO A:PRINT #2,X(J,I);:NEXT I:PRINT #2,:NEXT J:PRINT #2,:GOSUB 160
447 '<UNK! {000A}>--- Range Check ---
448 QB=3:PRINT:DO$="check EQUALITY of COLUMN DISPERSIONS"::GOSUB 20:IF Z$="N" THEN 474
449 GOSUB 43:FOR I=1 TO A:SM(I)=X(1,I):GR(I)=SM(I):FOR J=2 TO B:IF X(J,I)<SM(I) THEN SM(I)=X(J,I) ELSE IF X(J,I)>GR(I) THEN GR(I)=X(J,I)
450 NEXT J:NEXT I:SM=SM(1):FOR I=2 TO A:IF SM(I)<SM THEN SM=SM(I)
465 PRINT #2,:PRINT #2,:PRINT #2,"Using RANGE RATIOS (See BTS 31c, with k ="A"& n = "MID$(STR$(B),2)")"
466 PRINT #2,STRING$(63,"-")
467 PRINT #2,USING "ORIGINAL X "+F$;RR(1):IF QC<0 THEN 471
468 PRINT #2,USING "SQRT(X) "+S$+F$;RR(2)
469 IF QC=1 THEN PRINT #2,USING "LOG(X) "+S$+F$;RR(3):PRINT #2,USING "100/X "+S$+F$;RR(4):GOTO 471
470 IF QC=0 THEN PRINT #2,USING"LOG(X+1)"+S$+F$;RR(3):PRINT #2,USING "100/(X+1) "+F$;RR(4)
471 IF PR=0 THEN GOSUB 161:IF PR=1 THEN GOSUB 165:GOTO 454
472 IF PR=1 THEN PRINT #2,:GOSUB 160
473 '<UNK! {000A}>--- Transform? ---
474 IF T%=0 THEN DO$="transform all the data":GOSUB 20
475 IF Z$="Y" THEN GOSUB 250:IF T%<10 THEN DO$="re-view or print that transformed data":GOSUB 20:IF Z$="Y" THEN 436
476 '<UNK! {000A}>--- Calc (A = M = # cols. B = N = # rows) ---
477 GOSUB 43:FOR I=1 TO A:S(I)=0:FOR J=1 TO B:A(I)=A(I)+X(J,I):S(I)=S(I)+X(J,I)*X(J,I):NEXT J:AM(I)=A(I)/B:S2=S2+S(I):S(I)=(S(I)-A(I)*AM(I))/(B-1):S3=S3+A(I)*A(I):T=T+A(I):NEXT I
478 FOR J=1 TO B:FOR I=1 TO A:B(J)=B(J)+X(J,I):NEXT I:BM(J)=B(J)/A:S4=S4+B(J)*B(J):NEXT J
481 '<UNK! {000A}>--- Tukey's Non-additivity Test ---
482 S=0:FOR I=1 TO A-1:AL(I)=AM(I)-TM:S=S+AL(I):S5=S5+AL(I)*AL(I):NEXT I:AL(A)=-S:S5=S5+S*S:S=0:FOR J=1 TO B-1:BE(J)=BM(J)-TM:S=S+BE(J):S6=S6+BE(J)*BE(J):NEXT J
483 BE(B)=-S:S6=S6+S*S:FOR J=1 TO B:FOR I=1 TO A:TU(J)=TU(J)+X(J,I)*AL(I):NEXT I:NEXT J
484 S=0:FOR J=1 TO B:S=S+TU(J)*BE(J):NEXT J:SN=S*S/S5/S6:SR=SE-SN:DR=DE-1:VR=SR/DR
485 '<UNK! {000A}>--- Box's M ---
486 IF A<3 OR B<A THEN 500
487 FOR I=1 TO B:FOR J=1 TO A:FOR K=J TO A:D(J,K)=D(J,K)+X(I,J)*X(I,K):NEXT K:NEXT J:NEXT I
488 FOR J=1 TO A:FOR K=J TO A:D(J,K)=(D(J,K)-A(J)*AM(K))/(B-1):D(K,J)=D(J,K):C(J,K)=D(J,K):C(K,J)=C(J,K):NEXT K:NEXT J:M=A:GOSUB 360:D1=D
489 IF D1<=0 THEN 495 ELSE FOR I=1 TO M:DIAG=DIAG+D(I,I):NEXT I:DIAG=DIAG/M
490 FOR I=1 TO M-1:FOR J=I+1 TO M:ODIAG=ODIAG+D(I,J):NEXT J:NEXT I:ODIAG=ODIAG/(M*(M-1)/2)
491 FOR I=1 TO M:FOR J=1 TO M:IF I=J THEN C(I,I)=DIAG:D(I,I)=DIAG ELSE C(I,J)=ODIAG:D(I,J)=ODIAG
495 N=B:M=A-1:FOR I=1 TO N:FOR J=1 TO M:X(I,J)=X(I,J)-X(I,J+1):NEXT J:NEXT I:FOR J=1 TO M:FOR K=J TO M:D(J,K)=0:NEXT K:NEXT J
496 FOR I=1 TO N:FOR J=1 TO M:CM(J)=CM(J)+X(I,J):FOR K=J TO M:D(J,K)=D(J,K)+X(I,J)*X(I,K):NEXT K:NEXT J:NEXT I
497 FOR J=1 TO M:FOR K=J TO M:D(J,K)=(D(J,K)-CM(J)/N*CM(K))/(N-1):D(K,J)=D(J,K):C(J,K)=D(J,K):C(K,J)=C(J,K):NEXT K:NEXT J:FOR J=1 TO M:CM(J)=CM(J)/N:NEXT J:GOSUB 360:IF D=0 THEN 500
498 FOR J=1 TO M:X(1,J)=0:FOR K=1 TO M:X(1,J)=X(1,J)+CM(K)*C(K,J):NEXT K:NEXT J:FOR J=1 TO M:HOT=HOT+X(1,J)*CM(J):NEXT J:HOT=HOT*N:HF=HOT*(N-M)/(N-1)/M
499 ' df for Hot's F = M, N-M<UNK! {000A}><UNK! {000A}>--- Show Results ---
501 IF SA>1 THEN F2$=" ######.##" ELSE F2$=" ###.#####"
502 PRINT #2,:PRINT #2,"DATA SUMMARY";:IF T%>0 AND T%<10 THEN PRINT #2,S$"Transform = "T$(T%);
503 PRINT #2,S$;"Rows ="B;S$"Columns ="A:PRINT #2,:IF QD=1 THEN IF VN$="Y" THEN PRINT #2,"Columns are:":FOR I=1 TO A:PRINT #2,"#"USING"##=\ \ ";I;VN$(I);:NEXT I:PRINT #2,:PRINT #2,
504 F$="##=#####.### ":PRINT #2,USING"Grand Mean =#####.###";TM:PRINT #2,:PRINT #2,"Row Means:":FOR J=1 TO B:PRINT #2,"#"USING F$;J;BM(J);:NEXT J:PRINT #2,:PRINT #2,"Col Means:":FOR I=1 TO A:PRINT #2,"#"USING F$;I;AM(I);:NEXT I:PRINT #2,
505 PRINT#2,:PRINT #2,"Col Variances:":FOR I=1 TO A:PRINT #2,"#"USING F$;I;S(I);:NEXT I:PRINT #2,:IF PR=0 THEN GOSUB 5:CLS ELSE PRINT #2,:PRINT #2,
506 PRINT #2,"2-Way ANOVA assumes EQUAL CORRELATIONS between all pairs of TREATMENTS."
507 IF A<3 OR B<A OR D1<=0 THEN 508 ELSE 511
508 PRINT #2,"However, Box's Test for Equal Correlations cannot be done in the present case":PRINT #2,"because ";
509 IF A<3 THEN PRINT #2,"there are only 2 columns." ELSE IF B<A THEN PRINT #2,"there are more columns than rows." ELSE IF D1<=0 THEN PRINT #2,"the dispersion matrix has DET <= 0."
510 PRINT #2,:GOTO 513
511 PRINT #2,:PRINT #2,"Box's Test for Equal Correlations (Compound Symmetry):"
512 PRINT #2,USING" Det (DMAT) = #.####^^^^";D1:PRINT #2,USING" Det (Ave DMAT) = #.####^^^^";D2:PRINT #2,USING" Box's M =#####.##";BM:PRINT #2,USING" Chi-Sq =#####.## d.f.=###";BC;BD
513 GOSUB 5:IF PR=0 THEN CLS ELSE PRINT #2,:PRINT #2,
527 IF A<3 THEN PRINT #2,"....Can't be done with only 2 columns.":GOTO 539 ELSE IF B<A THEN PRINT #2,"....Can't be done since more columns than rows.":GOTO 539
529 PRINT #2," F ("MID$(STR$(M),2)","MID$(STR$(N-M),2)") =";:PRINT #2,USING"#####.##";HF:PRINT #2,:PRINT #2,USING" Det (CMAT) = #.####^^^^";D
530 IF PR=0 THEN PRINT #2,:PRINT #2,:PRINT #2,"Do you want to see Means & Dispersion Matrix of CHANGE SCORES,":PRINT #2,"for further analyses of columns";:GOSUB 21:IF Z$="Y" THEN ZC=1:CLS