How to control the format to export discriminant analysis results to word by using asdoc in Stata? - export

I want to export the results of a discriminant analysis by using asdoc in stata.
I want to show as follows.
three Three Decimal Digits.
compress the table to fit into a page of the word.
However, the format of the results is horrible. I use dec(3) but not working. I read the "help asdoc" in Stata, but it all about regression.
Does anyone know how to export the total results of discriminant analysis to Word with nice format?
Thank you in advance.
The following is the sample code and asdoc code that I use.
input area Revenue age child_number grocery_expense credit_card exercise_week social_week
1 99336 76 1 22453 5 3 1
1 59092 75 4 16995 6 1 3
1 68614 49 0 37709 0 7 5
1 84805 55 3 21642 0 3 1
1 66138 41 3 10490 2 4 7
1 90238 43 2 30254 5 6 4
1 60466 49 2 18136 1 0 4
1 46575 64 0 25053 6 6 7
2 97811 40 4 36925 4 6 5
2 61862 40 0 14480 5 5 6
2 58071 73 0 24754 4 0 1
2 42539 66 2 19903 3 1 6
2 62074 56 3 12560 3 3 7
2 71619 34 2 24523 6 3 6
2 51281 74 2 23625 4 6 3
3 40990 25 3 38943 4 7 4
3 44567 73 2 39898 1 4 7
3 73586 42 2 20159 0 2 3
3 44907 44 3 31378 1 1 6
3 79352 20 3 39968 6 6 1
3 55647 50 1 27122 0 3 6
3 80943 43 1 15177 2 7 4
3 88892 77 2 22537 4 2 7
4 91735 74 3 27505 0 5 2
4 61224 60 5 12374 5 1 0
4 72192 68 4 36817 2 6 1
4 87486 59 0 34846 6 5 1
4 53131 52 4 12584 5 1 1
4 49083 33 5 30652 3 0 5
4 47408 49 0 28938 1 6 0
4 74647 52 2 15291 0 5 6
5 81643 37 0 37993 2 4 2
5 42371 46 1 33436 6 5 4
5 74074 24 3 16618 5 6 7
5 63502 34 3 19887 1 4 3
5 86779 31 5 37290 6 3 4
5 45842 45 5 20383 2 1 5
5 59835 42 5 30708 4 2 1
5 60486 38 2 36167 3 6 2
5 49099 58 0 13157 4 3 7
5 71692 37 5 36317 4 6 3
5 91406 45 5 12451 5 7 1
6 42742 48 1 39088 5 2 0
6 54538 21 2 19657 0 7 3
6 49323 69 4 37173 5 5 5
6 50053 54 4 32193 2 7 7
6 99139 48 1 14647 4 4 1
6 97908 26 0 14319 6 1 4
6 46504 27 1 39478 4 6 2
6 92330 28 3 23676 1 3 0
6 93926 34 3 10871 1 3 3
6 81890 51 2 16914 1 0 1
6 86679 79 1 35967 2 7 6
6 43783 67 2 31009 2 5 0
6 76770 66 5 13220 6 6 7
6 91160 67 2 29346 6 0 3
end
asdoc candisc Revenue age child_number grocery_expense credit_card exercise_week social_week , group (area) dec(3)

Related

Problems with setting array elements in Forth

I am writing code in Forth that should create a 12x12 array of random numbers from 1 to 8.
create big_array 144 allocate drop
: reset_array big_array 144 0 fill ;
reset_array
variable rnd here rnd !
: random rnd # 31421 * 6927 + dup rnd ! ;
: choose random um* nip ;
: random_fill 144 1 do 8 choose big_array i + c! loop ;
random_fill
: Array_# 12 * + big_array swap + c# ;
: show_small_array cr 12 0 do 12 0 do i j Array_# 5 u.r loop cr loop ;
show_small_array
However, I notice that elements 128 to 131 of my array are always much larger than expected:
0 4 0 4 2 6 0 5 2 5 7 3
6 3 7 3 7 7 3 1 5 0 6 1
0 3 3 0 3 1 0 7 2 0 4 5
3 7 6 6 2 1 0 2 3 4 2 7
4 7 1 5 3 5 7 2 3 5 3 6
3 0 6 4 1 3 3 2 5 4 4 7
3 2 1 4 3 4 3 7 2 6 5 5
2 4 4 3 4 5 4 4 6 5 6 0
2 5 2 7 3 1 5 0 1 4 6 7
2 0 3 3 0 7 3 6 4 1 3 6
0 1 1 6 0 3 0 2 169 112 41 70
7 2 3 1 2 2 7 6 0 5 1 2
Moreover, when I try to change the value of these elements individually, this causes the other three elements to change value. For example, if I code:
9 choose big_array 128 + c!
then the array will become:
0 4 0 4 2 6 0 5 2 5 7 3
6 3 7 3 7 7 3 1 5 0 6 1
0 3 3 0 3 1 0 7 2 0 4 5
3 7 6 6 2 1 0 2 3 4 2 7
4 7 1 5 3 5 7 2 3 5 3 6
3 0 6 4 1 3 3 2 5 4 4 7
3 2 1 4 3 4 3 7 2 6 5 5
2 4 4 3 4 5 4 4 6 5 6 0
2 5 2 7 3 1 5 0 1 4 6 7
2 0 3 3 0 7 3 6 4 1 3 6
0 1 1 6 0 3 0 2 2 12 194 69
7 2 3 1 2 2 7 6 0 5 1 2
Do you have any idea why these specific elements are always impacted and if there is a way to prevent this?
Better readability and less error prone: 144 allocate ⇨ 144 chars allocate
A mistake: create big_array 144 allocate drop ⇨ create big_array 144 chars allot
A mistake: random um* nip ⇨ random swap mod
A mistake: 144 1 do ⇨ 144 0 do
An excessive operation: big_array swap + ⇨ big_array +
And add the stack comments, please. Especially, when you ask for help.
Do you have any idea why these specific elements are always impacted and if there is a way to prevent this?
Since you try to use memory in the dictionary space without reserving it. This memory is used by the Forth system.

J: Coordinates with specific value

Let's say we have array
0 1 2 3 4 5 8 7 8 9
There are two indexes that have value 8:
(i.10) ([#~8={) 0 1 2 3 4 5 8 7 8 9
6 8
Is there any shorter way to get this result? May be some built-in verb.
But more important. What about higher dimensions?
Let's say we have matrix 5x4
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
I want to find out what are coordinates with value 6.
I want to get result such (there are three coordinates):
4 1
3 2
2 3
It's pretty basic task and I think it should exist some simple solution.
The same in three dimensions?
Thank you
Using Sparse array functionality ($.) provides a very fast and lean solution that also works for multiple dimensions.
]a=: 5 ]\ 1 + i. 8
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
6 = a
0 0 0 0 0
0 0 0 0 1
0 0 0 1 0
0 0 1 0 0
4 $. $. 6 = a
1 4
2 3
3 2
Tacitly:
getCoords=: 4 $. $.
getCoords 6 = a ,: a
0 1 4
0 2 3
0 3 2
1 1 4
1 2 3
1 3 2
Verb indices I. almost does the job.
When you have a simple list, I.'s use is straightforward:
I. 8 = 0 1 2 3 4 5 8 7 8 9
6 8
For higher order matrices you can pair it with antibase #: to get the coordinates in base $ matrix. Eg:
]a =: 4 5 $ 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8
1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8
I. 6 = ,a
9 13 17
($a) #: 9 13 17
1 4
2 3
3 2
Similarly, for any number of dimensions: flatten (,), compare (=), get indices (I.) and convert coordinates (($a)&#:):
]coords =: ($a) #: I. 5 = , a =: ? 5 6 7 $ 10
0 0 2
0 2 1
0 2 3
...
(<"1 coords) { a
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
By the way, you can write I. x = y as x (I.#:=) y for extra performance. It is special code for
indices where x f y

Sum row vectors IF two or more rows in given column match (MATLAB)

I have a 48x202 matrix, where the first columns in the matix is an ID, and the rest of the columns is related vectors to the row ID in the first column.
The ID column is sorted in acending order, and multiple rows can have the same ID.
I want to summarize all IDs that are equal, meaning that i want to sum the rows in the matrix who has identical ID in the first column.
The resulting matrix should be 32x202, since there are only 32 IDs.
Any ideas?
I'd totally approach this with accumarray as well as unique. Like the previous answer, let A be your matrix. You would obtain your answer thusly:
[vals,~,id] = unique(A(:,1),'stable');
B = accumarray(id, (1:numel(id)).', [], #(x) {sum(A(x,2:end),1)});
out = [vals cell2mat(B)];
The first line of code produces vals which is a list of all unique IDs seen in the first column of A and id assigns a unique integer ID without any gaps from 1 up to as many unique IDs there are in the first column of A. The reason why you want to do this is for the next line of code.
How accumarray works is that you provide a set of keys and a set of values associated with each key. accumarray groups all values that belong to the same key and does something to all of the values. The keys in our case is the IDs given in the first column of A and the values are the actual row locations of the matrix A from 1 up to as many rows as A. Now, the default behaviour when collecting all of the values together is to sum all of the values that belong to the same key together, but we're going to do something a bit different. What we'll do is that for each unique ID seen in the first column of A, there will be a bunch of row locations that map to the same ID. We're going to use these row locations and will access the matrix A and sum all of the columns from the second column to the end. That's what the anonymous function in the fourth argument of accumarray is doing. accumarray traditionally should output a single value representing all of the values mapped to a key, but we get around this by outputting a single cell, where each cell entry is the row sum of the mapped columns.
Each element of B gives you the row sum for each corresponding unique value in vals and so the last line of code pieces these together - the unique value in vals with the corresponding row sum. I had to use cell2mat because this was a matrix of cells and I had to convert all of these into a numerical matrix to complete the task.
Here's an example seeing this in action. I'm going to do this for a smaller set of data:
>> rng(123);
>> A = [[1;1;1;2;2;2;2;3;3;4;4;5;6;7] randi(10, 14, 10)];
>> A
A =
1 7 4 3 4 5 1 10 3 2 3
1 3 8 7 5 7 9 9 4 9 6
1 3 2 1 9 9 7 4 6 4 9
2 6 2 5 3 6 8 1 7 6 4
2 8 6 5 5 7 1 4 2 6 8
2 5 6 5 10 6 6 4 2 6 2
2 10 7 5 6 7 6 8 4 1 7
3 7 9 4 7 7 2 10 7 10 9
3 5 8 5 2 9 2 4 9 10 10
4 4 7 9 9 1 7 8 6 3 1
4 4 8 10 7 8 4 6 9 3 5
5 8 4 6 6 3 7 7 4 6 3
6 5 4 7 4 2 6 2 4 10 5
7 1 3 2 4 6 4 4 4 10 6
The first column is our IDs, and the next columns are the data. Running the above code I just wrote, we get:
>> out
out =
1 13 14 11 18 21 17 23 13 15 18
2 29 21 20 24 26 21 17 15 19 21
3 12 17 9 9 16 4 14 16 20 19
4 8 15 19 16 9 11 14 15 6 6
5 8 4 6 6 3 7 7 4 6 3
6 5 4 7 4 2 6 2 4 10 5
7 1 3 2 4 6 4 4 4 10 6
If you double check each row, summing over all of the columns that match each of the column IDs matches up. For example, the first three rows map to the same ID, and we should sum up all of these rows and we get the corresponding sum. The second column is equal to 7+3+3=13, the third column is equal to 4+8+2=14, etc.
Another approach is to apply unique and then use bsxfun to build a matrix that multiplied by the non-ID part of the input matrix will give the result.
Let the input matrix be denoted as A. Then:
[u, ~, v] = unique(A(:,1));
result = [ u bsxfun(#eq, u, u(v).') * A(:,2:end) ];
Example: borrowing from #rayryeng's answer, let
A = [ 1 7 4 3 4 5 1 10 3 2 3
1 3 8 7 5 7 9 9 4 9 6
1 3 2 1 9 9 7 4 6 4 9
2 6 2 5 3 6 8 1 7 6 4
2 8 6 5 5 7 1 4 2 6 8
2 5 6 5 10 6 6 4 2 6 2
2 10 7 5 6 7 6 8 4 1 7
3 7 9 4 7 7 2 10 7 10 9
3 5 8 5 2 9 2 4 9 10 10
4 4 7 9 9 1 7 8 6 3 1
4 4 8 10 7 8 4 6 9 3 5
5 8 4 6 6 3 7 7 4 6 3
6 5 4 7 4 2 6 2 4 10 5
7 1 3 2 4 6 4 4 4 10 6 ];
Then the result is
result =
1 13 14 11 18 21 17 23 13 15 18
2 29 21 20 24 26 21 17 15 19 21
3 12 17 9 9 16 4 14 16 20 19
4 8 15 19 16 9 11 14 15 6 6
5 8 4 6 6 3 7 7 4 6 3
6 5 4 7 4 2 6 2 4 10 5
7 1 3 2 4 6 4 4 4 10 6
and the intermediate matrix created with bsxfun is
>> bsxfun(#eq, u, u(v).')
ans =
1 1 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1
Pre-multiplying A by this matrix means that the first three rows of A are added to give the first row of the result; then the following four rows of A are added to give the second row of the result, etc.
You can find the unique row IDs with unique and then loop over all of those, summing the other columns: Let A be your matrix, then
rID = unique(A(:, 1));
B = zeros(numel(rID), size(A, 2));
for ii = 1:numel(rID)
B(ii, 1) = rID(ii);
B(ii, 2:end) = sum(A(A(:, 1) == rID(ii), 2:end), 1);
end
B contains your output.

How can I find the index of the last greater than or equals value in one array, for all values in the first array? MATLAB

I have 2 vectors. A is a list of dates, every day for 3 years. B is a list of (option expiration) dates, which occur once a month.
A is therefore much larger than B. I want a vector the length of A, which for each entry in A finds the index of the last >= value in B.
In this way I can get an expiration date (from B) for every date in my vector A.
I would like to accomplish this without using a loop.
Thanks for the help.
Edit: A, B below (abbreviated)
B = 735126
735154
735189
735217
735245
735280
735308
735336
735364
735399
735427
735462
735490
735518
735553
735581
735609
735644
A = 735126
735127
735128
735129
735130
735131
735132
735133
735134
735135
735136
735137
735138
735139
735140
735141
735142
735143
735144
735145
735146
735147
735148
735149
735150
735151
735152
735153
735154
735155
735156
735157
735158
735159
735160
735161
735162
735163
735164
735165
735166
735167
735168
735169
735170
735171
735172
735173
735174
735175
735176
735177
735178
735179
735180
735181
735182
735183
735184
735185
735186
735187
735188
735189
735190
735191
735192
735193
735194
735195
735196
735197
735198
735199
735200
735201
735202
735203
735204
735205
735206
735207
735208
735209
735210
735211
735212
735213
735214
735215
735216
735217
735218
735219
735220
735221
735222
735223
735224
735225
735226
735227
735228
735229
735230
735231
735232
735233
735234
735235
735236
735237
735238
735239
735240
735241
735242
735243
735244
735245
735246
735247
735248
735249
735250
735251
735252
735253
735254
735255
735256
735257
735258
735259
735260
735261
735262
735263
735264
735265
735266
735267
735268
735269
735270
735271
735272
735273
735274
735275
735276
735277
735278
735279
735280
735281
735282
735283
735284
735285
735286
735287
735288
735289
735290
735291
735292
735293
735294
735295
735296
735297
735298
735299
735300
735301
735302
735303
735304
735305
735306
735307
735308
735309
735310
735311
735312
735313
735314
735315
735316
735317
735318
735319
735320
735321
735322
735323
735324
735325
735326
735327
735328
735329
735330
735331
735332
735333
735334
735335
735336
735337
735338
735339
735340
735341
735342
735343
735344
735345
735346
735347
735348
735349
735350
735351
735352
735353
735354
735355
735356
735357
735358
735359
735360
735361
735362
735363
735364
735365
735366
735367
735368
735369
735370
735371
735372
735373
735374
735375
735376
735377
735378
735379
735380
735381
735382
735383
735384
735385
735386
735387
735388
735389
735390
735391
735392
735393
735394
735395
735396
735397
735398
735399
735400
735401
735402
735403
735404
735405
735406
735407
735408
735409
735410
735411
735412
735413
735414
735415
735416
735417
735418
735419
735420
735421
735422
735423
735424
735425
735426
735427
735428
735429
735430
735431
735432
735433
735434
735435
735436
735437
735438
735439
735440
735441
735442
735443
735444
735445
735446
735447
735448
735449
735450
735451
735452
735453
735454
735455
735456
735457
735458
735459
735460
735461
735462
735463
735464
735465
735466
735467
735468
735469
735470
735471
735472
735473
735474
735475
735476
735477
735478
735479
735480
735481
735482
735483
735484
735485
735486
735487
735488
735489
735490
735491
735492
735493
735494
735495
735496
735497
735498
735499
735500
735501
735502
735503
735504
735505
735506
735507
735508
735509
735510
735511
735512
735513
735514
735515
735516
735517
735518
735519
735520
735521
735522
735523
735524
735525
735526
735527
735528
735529
735530
735531
735532
735533
735534
735535
735536
735537
735538
735539
735540
735541
735542
735543
735544
735545
735546
735547
735548
735549
735550
735551
735552
735553
735554
735555
735556
735557
735558
735559
735560
735561
735562
735563
735564
735565
735566
735567
735568
735569
735570
735571
735572
735573
735574
735575
735576
735577
735578
735579
735580
735581
735582
735583
735584
735585
735586
735587
735588
735589
735590
735591
735592
735593
735594
735595
735596
735597
735598
735599
735600
735601
735602
735603
735604
735605
735606
735607
735608
735609
735610
735611
735612
Answer (using Excel) =
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
4
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
6
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
7
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
8
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
9
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
10
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
11
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
12
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
13
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
14
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
15
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
16
17
17
17
17
I'm assuming you want the last value of B such that all values up to that one satisfy the condition.
[~, result] = max(bsxfun(#gt, B(:), A(:).'), [], 1);
result = result-1;
result(~result) = numel(B);
Example:
>> A = [1 9 6 8 5];
>> B = [1 3 7 2];
>> [~, result] = max(bsxfun(#gt, B(:), A(:).'), [], 1);
>> result = result-1;
>> result(~result) = numel(B);
gives
A =
1 9 6 8 5
B =
1 3 7 2
result =
1 4 2 4 2
One approach -
[~,idx] = max(cumsum(bsxfun(#ge,A(:),B(:).'),2),[],2)
If you would like to remove cumsum -
[~,idx] = max(bsxfun(#ge,A(:),fliplr(B(:).')),[],2);
idx = numel(B) - idx + 1
Sample run -
>> A,B
A =
1 6 7 9 0 2 4 9 5
B =
0 2 8 4 5
>> idx
idx =
1
5
5
5
1
2
4
5
5

Reshape acast() remove missing values

I have this dataframe:
df <- data.frame(subject = c(rep("one", 20), c(rep("two", 20))),
score1 = sample(1:3, 40, replace=T),
score2 = sample(1:6, 40, replace=T),
score3 = sample(1:3, 40, replace=T),
score4 = sample(1:4, 40, replace=T))
subject score1 score2 score3 score4
1 one 2 4 2 2
2 one 3 3 1 2
3 one 1 2 1 3
4 one 3 4 1 2
5 one 1 2 2 3
6 one 1 5 2 4
7 one 2 5 3 2
8 one 1 5 1 3
9 one 3 5 2 2
10 one 2 3 3 4
11 one 3 2 1 3
12 one 2 5 2 1
13 one 2 4 1 4
14 one 2 2 1 3
15 one 1 3 1 4
16 one 1 6 1 3
17 one 3 4 2 2
18 one 3 2 1 3
19 one 2 5 3 1
20 one 3 6 2 1
21 two 1 6 3 4
22 two 1 2 1 2
23 two 3 2 1 2
24 two 1 2 2 1
25 two 2 3 1 3
26 two 1 5 3 3
27 two 2 4 1 4
28 two 2 6 2 4
29 two 1 6 2 2
30 two 1 5 1 4
31 two 2 1 2 4
32 two 3 6 1 1
33 two 1 1 3 1
34 two 2 4 2 3
35 two 2 1 3 2
36 two 2 3 1 3
37 two 1 2 3 4
38 two 3 5 2 2
39 two 2 1 3 4
40 two 2 1 1 3
Note that the scores have different ranges of values. Score 1 ranges from 1-3, score 2 from -6, score 3 from 1-3, score 4 from 1-4
I'm trying to reshape data like this:
library(reshape2)
dfMelt <- melt(df, id.vars="subject")
acast(dfMelt, subject ~ value ~ variable)
Aggregation function missing: defaulting to length
, , score1
1 2 3 4 5 6
one 6 7 7 0 0 0
two 8 9 3 0 0 0
, , score2
1 2 3 4 5 6
one 0 5 3 4 6 2
two 5 4 2 2 3 4
, , score3
1 2 3 4 5 6
one 10 7 3 0 0 0
two 8 6 6 0 0 0
, , score4
1 2 3 4 5 6
one 3 6 7 4 0 0
two 3 5 5 7 0 0
Note that the output array includes scores as "0" if they are missing. Is there any way to stop these missing scores being outputted by acast?
In this case, you might do better sticking to base R's table feature. I'm not sure that you can have an irregular array like you are looking for.
For example:
> lapply(df[-1], function(x) table(df[[1]], x))
$score1
x
1 2 3
one 9 6 5
two 11 4 5
$score2
x
1 2 3 4 5 6
one 2 5 4 3 3 3
two 4 2 2 3 4 5
$score3
x
1 2 3
one 9 5 6
two 4 11 5
$score4
x
1 2 3 4
one 4 4 8 4
two 2 6 5 7
Or, using your "long" data:
with(dfMelt, by(dfMelt, variable,
FUN = function(x) table(x[["subject"]], x[["value"]])))
Since each "score" subset is going to have a different shape, you will not be able to preserve the array structure. One option is to use lists of two-dim arrays or data.frames. eg:
# your original acast call
res <- acast(dfMelt, subject ~ value ~ variable)
# remove any columns that are all zero
apply(res, 3, function(x) x[, apply(x, 2, sum)!=0] )
Which gives:
$score1
1 2 3
one 7 8 5
two 6 8 6
$score2
1 2 3 4 5 6
one 4 2 6 4 1 3
two 2 5 3 4 3 3
$score3
1 2 3
one 5 10 5
two 5 11 4
$score4
1 2 3 4
one 5 4 4 7
two 4 6 6 4

Resources