Data Structure for Sequence of Event Analysis in R - arrays

The code below creates a sample dataframe to illustrate my problem. I have a time stamped list of events.
set.seed(100)
mydf<-data.frame(time=(1:1000),event = sample(1:10,10000,replace=TRUE))
mydf
time event
1 6
2 5
3 7
4 8
5 4
6 2
7 10
8 9
9 4
10 6
11 4
12 3
13 8
14 3
15 9
16 1
17 7
18 3
19 8
20 10
I am trying to create a new variable that lists the previous events in a specified window. say the window is size 10. I would like to create the dataframe below. My ultimate goal is to prepare my data for sequence of events analysis.
time event eventList
1 6 NA
2 5 NA
3 7 NA
4 8 NA
5 4 NA
6 2 NA
7 10 NA
8 9 NA
9 4 NA
10 6 NA
11 4 {6,5,7,8,4,2,10,9,4,6}
12 3 {5,7,8,4,2,10,9,4,6,4}
13 8 {7,8,4,2,10,9,4,6,4,3}
14 3 {8,4,2,10,9,4,6,4,3,8}
15 9 {4,2,10,9,4,6,4,3,8,3}
16 1 {2,10,9,4,6,4,3,8,3,9}
17 7 {10,9,4,6,4,3,8,3,9,1}
18 3 {9,4,6,4,3,8,3,9,1,7}
19 8 {4,6,4,3,8,3,9,1,7,8}
20 10 {6,4,3,8,3,9,1,7,8,10}

The last three rows do not match , could you please check your expected output
mydf=read.table(text="
time event
1 6
2 5
3 7
4 8
5 4
6 2
7 10
8 9
9 4
10 6
11 4
12 3
13 8
14 3
15 9
16 1
17 7
18 3
19 8
20 10",header=TRUE,stringsAsFactors=FALSE)
windowSize = 10
mydf$eventList = do.call(rbind,lapply(mydf$time,function(x) {
ifelse(x<windowSize,NA,paste0("{", paste0(mydf[ tail(1:x,windowSize) ,"event"],collapse=",") , "}"))
}))
mydf
# time event eventList
#1 1 6 <NA>
#2 2 5 <NA>
#3 3 7 <NA>
#4 4 8 <NA>
#5 5 4 <NA>
#6 6 2 <NA>
#7 7 10 <NA>
#8 8 9 <NA>
#9 9 4 <NA>
#10 10 6 {6,5,7,8,4,2,10,9,4,6}
#11 11 4 {5,7,8,4,2,10,9,4,6,4}
#12 12 3 {7,8,4,2,10,9,4,6,4,3}
#13 13 8 {8,4,2,10,9,4,6,4,3,8}
#14 14 3 {4,2,10,9,4,6,4,3,8,3}
#15 15 9 {2,10,9,4,6,4,3,8,3,9}
#16 16 1 {10,9,4,6,4,3,8,3,9,1}
#17 17 7 {9,4,6,4,3,8,3,9,1,7}
#18 18 3 {4,6,4,3,8,3,9,1,7,3}
#19 19 8 {6,4,3,8,3,9,1,7,3,8}
#20 20 10 {4,3,8,3,9,1,7,3,8,10}

I am assuming someone will come up with a more R way of going this, reducing your runtime. Meanwhile you can try this:
for (i in 1:nrow(mydf)){
if(i<=w){
mydf$eventList[i] = NA
}
else {
mydf$eventList[i] = list(mydf$event[c((i-w):i)])
}
}

Related

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

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)

Rotate matrix elements

Given a 2D array A. Write a program that rotate/shift the elements of an array clockwise by one at a time.
Example:
Input
1 2 3 4 
5 6 7 8 
9 10 11 12 
13 14 15 16
Output
5 1 2 3 
9 10 6 4 
13 11 7 8 
14 15 16 12

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

R create an array result of cutting (seq) of a data frame

I'm not comfortable with array manipulation (and english writing, sorry ..)
I've this data frame (aa):
aa<-data.frame(replicate(10,sample(0:17,30,rep=TRUE)))
> aa
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1 17 7 9 2 3 7 17 0 15 1
2 12 5 10 10 8 17 13 7 2 2
3 14 14 7 7 16 1 13 0 14 6
4 12 10 10 15 7 2 7 11 4 0
5 1 9 5 5 8 15 15 11 8 17
6 8 0 9 6 7 11 9 12 4 17
7 17 1 17 5 11 8 16 0 2 15
8 10 7 15 6 17 3 0 16 16 15
9 8 3 14 13 16 5 15 8 14 10
10 11 13 15 3 17 13 13 4 11 12
11 9 13 0 7 4 13 15 1 2 0
12 1 3 17 13 10 4 12 5 4 15
13 5 8 9 8 0 6 14 13 0 8
14 17 11 10 4 15 10 7 1 1 7
15 2 0 16 7 13 10 13 3 10 7
16 5 5 15 7 0 17 10 14 11 4
17 10 17 9 11 0 9 9 17 0 4
18 12 8 8 16 11 4 10 16 4 7
19 5 7 13 12 17 17 17 17 6 8
20 13 17 1 2 0 1 8 4 17 17
21 15 15 5 13 6 16 5 5 14 13
22 12 4 5 1 2 7 17 2 9 9
23 12 5 13 16 6 6 15 2 13 10
24 8 6 12 4 5 11 7 12 14 10
25 5 11 15 1 17 3 8 10 4 4
26 3 10 8 14 1 13 16 1 16 11
27 10 2 14 11 6 8 13 3 8 10
28 14 5 7 12 8 14 16 9 16 14
29 5 17 16 17 12 1 3 8 2 0
30 5 17 12 2 8 9 3 1 14 15
I would like to create an array wich is the result of a cutting of dataframe (aa) like this (by seq of x elements, here for exemple 10): an array with 3 dimensions
, , 1
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
1 17 7 9 2 3 7 17 0 15 1
2 12 5 10 10 8 17 13 7 2 2
3 14 14 7 7 16 1 13 0 14 6
4 12 10 10 15 7 2 7 11 4 0
5 1 9 5 5 8 15 15 11 8 17
6 8 0 9 6 7 11 9 12 4 17
7 17 1 17 5 11 8 16 0 2 15
8 10 7 15 6 17 3 0 16 16 15
9 8 3 14 13 16 5 15 8 14 10
10 11 13 15 3 17 13 13 4 11 12
, , 2
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
11 9 13 0 7 4 13 15 1 2 0
12 1 3 17 13 10 4 12 5 4 15
13 5 8 9 8 0 6 14 13 0 8
14 17 11 10 4 15 10 7 1 1 7
15 2 0 16 7 13 10 13 3 10 7
16 5 5 15 7 0 17 10 14 11 4
17 10 17 9 11 0 9 9 17 0 4
18 12 8 8 16 11 4 10 16 4 7
19 5 7 13 12 17 17 17 17 6 8
20 13 17 1 2 0 1 8 4 17 17
etc...
i've already tried this...
aa_lag <-array(aa[1:10,],dim=c(dim(aa),3))
thank you so much for answer...
You can try
aa1 <- t(aa)
dim(aa1) <- c(10,10,3)
aa2 <- aperm(aa1, c(2,1,3))
Checking the results
m1 <- as.matrix(aa[1:10,])
dimnames(m1) <- NULL
identical(m1, aa2[,,1])
#[1] TRUE
Or using seq
lst <- lapply(seq(1,30, by=10), function(i) aa[i:(i+9),])
aa3 <- array(unlist(lst), dim=c(10,10,3))
identical(aa2, aa3)
#[1] TRUE
data
set.seed(24)
aa<-data.frame(replicate(10,sample(0:17,30,rep=TRUE)))

matlab get neighbours on matrix

I have a simple matrix:
1 2 3 4
5 6 7 8
8 9 10 11
12 13 14 15
I need to loop through each element and build a new matrix with 3 of its surrounding elements (the one to the right, bottom right and bottom). So I will end up with an array like so:
1 2 6 5
2 3 7 6
3 4 8 7
I managed to do this but when I need to jump to the row below I can't seem to figure out how to do it. for the next row it should be:
5 6 9 8
6 7 10 9
...
Any ideas?
[m n] = size(A);
[jj ii] = ndgrid(1:m-1, 1:n-1); %// rows and columns except last ones
kk = sub2ind([m n], ii(:),jj(:)); %// to linear index
B = [ A(kk) A(kk+m) A(kk+m+1) A(kk+1) ] %// pick desired values with linear index
In your example:
B =
1 2 6 5
2 3 7 6
3 4 8 7
5 6 9 8
6 7 10 9
7 8 11 10
8 9 13 12
9 10 14 13
10 11 15 14
My favourite bsxfun being put to work here -
[M,N] = size(A); %// A is Input
ind = bsxfun(#plus,[1:M-1],[(0:N-2).*M]') %//'
out = A(bsxfun(#plus,ind(:),[0 M M+1 1])) %// Desired output
Output using the sample input from question -
out =
1 2 6 5
2 3 7 6
3 4 8 7
5 6 9 8
6 7 10 9
7 8 11 10
8 9 13 12
9 10 14 13
10 11 15 14

Resources