1 ' 2-WAY ANOVA, REPLICATED --- ANOVR.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 400,177,447,10 :STOP '=start,printout,etc - CLOSE (exc 177)<UNK! {000A}><UNK! {000A}>--- Another go? ---
10 CLOSE: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
46 ZZ$=STRING$(37-LEN(Z$)\2,177):LOCATE 1,1:PRINT ZZ$" ";:COLOR 15,0:PRINT Z$;:COLOR 7,0:PRINT" "ZZ$:RETURN 'Display brightened Z$ at top of screen
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 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
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. Also ZZ$="UTOK" if UT is acceptable.
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 AND ZZ$<>"UTOK" 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>MXV 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 ' 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 '
92 IF NEEDVARS=1 THEN PRINT"This test analyses only 1 column variable at a time.":ND=M-1
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:KL=J
98 NEXT J
99 ' ******** Now read data values from disk
100 COLOR 23,0:PRINT"Loading numbers";:COLOR 7,0:DIM XX(N,M):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 XX(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
424 PRINT:PRINT"Options: 1. Equal # of replicates in each cell.<UNK! {000A}>"TAB(K)"2. Weighted Means Analysis for Unequal replicates.<UNK! {000A}>"TAB(K)"3. Unweighted Means Analysis for Unequal replicates.<UNK! {000A}>"TAB(K)"4. Return to Main Menu."
425 LOCATE ,,1:PRINT
426 INPUT"===> Which do you want (1-4) ";OP:IF OP<1 OR OP>4 THEN BEEP:GOTO 426 ELSE IF OP=4 THEN 30
427 '<UNK! {000A}>--- Get Data ---<UNK! {000A}> Note: X(I,J) with B rows & A cols, I=1 to AB cells, J=1 to N(I) reps/cell.
428 DO$="enter data from disk":GOSUB 20:PRINT:IF Z$="Y" THEN 458
429 '<UNK! {000A}>--- K/b Entry ---
430 ' Get Datatable Sizes
431 INPUT"No. of Row Levels (2-20) ";X$:B=VAL(X$):IF B<2 OR B>MXR THEN 431
432 INPUT"No. of Column Levels (2-10) ";X$:A=VAL(X$):IF A<2 OR A>MXC THEN 432
433 AB=A*B:DIM N(AB) 'to hold reps/cell
434 IF OP>1 THEN 437 INPUT"No. of Replicates per Cell (2-50) ";R:IF R<2 OR R>50 THEN 434
435 INPUT"No. of Replicates per Cell (2-50) ";X$:R=VAL(X$):IF R<2 OR R>50 THEN 435
436 N2=AB*R:IF N2>MXV THEN BEEP:PRINT "Exceeds max"MXV"measurements!":GOSUB 5:GOTO 400 ELSE N=N2:FOR I=1 TO AB:N(I)=R:NEXT I:GOTO 442
437 FOR J=1 TO B:FOR I=1 TO A
438 PRINT"No. of Replicates in Row"J", Col"I;:INPUT X$:R=VAL(X$):IF R<2 OR R>50 THEN BEEP:PRINT"No, must be 2-50.":GOTO 438
439 IF QD=1 AND N2+R>N THEN PRINT"Oops, too many! Try again.":GOTO 438
440 N2=N2+R:N((J-1)*A+I)=R:IF R>GR THEN GR=R
441 NEXT I:NEXT J:R=GR:N=N2
442 DIM X(AB,R),NI(A),NJ(B),A(A),AM(A),B(B),BM(B),C(AB),CM(AB),GR(AB),SM(AB),R(AB),Y(AB),V(AB),AP(A),BP(B):IF QD=1 THEN RETURN
443 '<UNK! {000A}>--- Enter Data ---
444 PRINT:PRINT"Enter Measurements by Cells, with 1 Measurement per Line:":K=0
445 FOR J=1 TO B:FOR I=1 TO A:PRINT"Cell at Row"J", Col"I":":FOR K=1 TO N((J-1)*A+I):PRINT"#"K;:INPUT X$:GOSUB 370:X((J-1)*A+I,K)=VAL(X$):NEXT K:NEXT I:NEXT J:IF OP>1 THEN N=N2
446 '<UNK! {000A}>--- Show Data ---
447 QB=3:CLOSE:CLS:PRINT"DATA READ WAS:"
448 FOR J=1 TO B:FOR I=1 TO A:PRINT:PRINT"Row "MID$(STR$(J),2)", Col "MID$(STR$(I),2)":"
449 FOR K=1 TO N((J-1)*A+I):PRINT X((J-1)*A+I,K)" ";:NEXT K:PRINT
450 '<UNK! {000A}>--- Edit ---
451 INPUT"Edit (C#=Change Datum #, SA=Show All, N=None)";Z$:IF Z$="" OR Z$="N" OR Z$="n" THEN 455
452 IF Z$="SA" OR Z$="sa" THEN 447 ELSE IF LEFT$(Z$,1)="C" OR LEFT$(Z$,1)="c" THEN Z=VAL(MID$(Z$,2)):IF Z>0 AND Z<=N((J-1)*A+I) THEN PRINT"#"Z"="X((J-1)*A+I,Z):GOTO 454
453 PRINT"SILLY. ";:GOTO 451
454 PRINT"Right Value ";:INPUT X$:IF X$="" THEN 454 ELSE X((J-1)*A+I,Z)=VAL(X$):PRINT"Row "MID$(STR$(J),2)", Col "MID$(STR$(I),2)" is now:":GOTO 449
455 LOCATE CSRLIN-1,1:PRINT SPACE$(60);:LOCATE ,1
456 NEXT I:NEXT J:GOTO 462
457 '<UNK! {000A}>--- Disk Entry ---
458 QD=1:MNR=2:MNC=1:GOSUB 80:GOSUB 431
459 K=0:FOR I=1 TO AB:FOR J=1 TO N(I):K=K+1:X(I,J)=XX(K,1):NEXT J:NEXT I
460 GOTO 447
461 '<UNK! {000A}>--- Print Data ---
462 DO$="print this data":GOSUB 20:IF Z$="N" THEN 467 ELSE GOSUB 162:GOSUB 165:IF VN$<>"Y"THEN PRINT #2,"Variable not named." ELSE PRINT #2,"Variable #"KL"= "VN$(KL)"."
463 PRINT #2,:IF T%=0 OR T%=10 THEN PRINT #2,"DATA:" ELSE PRINT #2,"DATA, with Transform ="T$(T%)"."
464 FOR J=1 TO B:FOR I=1 TO A:PRINT #2,:PRINT #2,"Row "MID$(STR$(J),2)", Col "MID$(STR$(I),2)":":FOR K=1 TO N((J-1)*A+I):PRINT #2,X((J-1)*A+I,K);:NEXT K:PRINT #2,:NEXT I:NEXT J:PRINT #2,:GOSUB 160
465 IF T%>0 THEN 505
466 '<UNK! {000A}>--- Range Check ---
467 DO$="check EQUALITY of CELL DISPERSIONS":GOSUB 20:IF Z$="N" THEN 502
468 GOSUB 43:FOR I=1 TO AB:SM(I)=X(I,1):GR(I)=SM(I):FOR J=2 TO N(I):IF X(I,J)<SM(I) THEN SM(I)=X(I,J) ELSE IF X(I,J)>GR(I) THEN GR(I)=X(I,J)
469 NEXT J:NEXT I:SM=SM(1):FOR I=2 TO AB:IF SM(I)<SM THEN SM=SM(I)
470 NEXT I:QC=SGN(SM)
471 IF OP=1 THEN 476 ELSE CLS:PRINT"Cells have UNEQUAL REPLICATES, so enter d(n) values from BTS 27:":PRINT"d("MID$(STR$(N(1)),2)")";:INPUT Y(1)
472 FOR I=2 TO AB:FOR J=1 TO I-1:IF N(I)=N(J) THEN Y(I)=Y(J):J=I:FLAG=1
492 IF OP=1 THEN PRINT #2,"Using RANGE RATIOS (See BTS 31c, with k ="AB"& n = "MID$(STR$(N(1)),2)")"
493 IF OP>1 THEN PRINT #2,"Using MAX F RATIOS (See BTS 31, with k ="AB"& nu = "MID$(STR$(INT(N/AB+P5)-1),2)")"
494 PRINT #2,STRING$(63,"-")
495 PRINT #2,USING"ORIGINAL X "+F$;RR(1):IF QC<0 THEN 499
496 PRINT #2,USING"SQRT(X) "+S$+F$;RR(2)
497 IF QC=1 THEN PRINT #2,USING"LOG(X) "+S$+F$;RR(3):PRINT #2,USING"100/X "+S$+F$;RR(4):GOTO 499
498 IF QC=0 THEN PRINT #2,USING"LOG(X+1)"+S$+F$;RR(3):PRINT #2,USING"100/(X+1) "+F$;RR(4)
499 IF PR=0 THEN GOSUB 161:IF PR=1 THEN GOSUB 165:GOTO 478
500 IF PR=0 THEN GOSUB 160
501 '<UNK! {000A}>--- Transform? ---
502 IF T%>0 THEN 505 ELSE DO$="transform all the data":GOSUB 20
503 IF Z$="Y" THEN GOSUB 250:IF T%<10 THEN DO$="re-view or print that transformed data":GOSUB 20:IF Z$="Y" THEN CLS:PRINT"TRANSFORMED DATA:":GOTO 448
504 '<UNK! {000A}>--- Calc (A = # cols, B = # rows) ---
505 QB=4:CLOSE:GOSUB 43:FOR I=1 TO AB:FOR K=1 TO N(I):C(I)=C(I)+X(I,K):V(I)=V(I)+X(I,K)*X(I,K):NEXT K:CM(I)=C(I)/N(I):S2=S2+V(I):V(I)=(V(I)-C(I)*C(I)/N(I))/(N(I)-1):S5=S5+C(I)*C(I)/N(I):NEXT I
506 FOR I=1TO A:FOR J=I TO AB STEP A:A(I)=A(I)+C(J):NI(I)=NI(I)+N(J):NEXT J:NEXT I
541 IF PR=0 THEN PRINT #2,:GOSUB 5:GOSUB 161:IF PR=1 THEN GOSUB 165:GOTO 515
542 GOSUB 160:GOTO 10
543 '<UNK! {000A}>--- Unweighted Means ---
544 FOR I=1 TO AB:HM=HM+1/N(I):NEXT I:HM=AB/HM:FOR J=1 TO B:FOR I=1 TO A:S6=S6+CM((J-1)*A+I)*CM((J-1)*A+I):AP(I)=AP(I)+CM((J-1)*A+I):BP(J)=BP(J)+CM((J-1)*A+I):NEXT I:TP=TP+BP(J):NEXT J
545 S3=0:FOR I=1 TO A:AM(I)=AP(I)/B:S3=S3+AP(I)*AP(I):NEXT I:S3=S3/B:S4=0:FOR J=1 TO B:BM(J)=BP(J)/A:S4=S4+BP(J)*BP(J):NEXT J