I have a dataset like:
ID X t1 t2
1 01 A 1 4
2 01 A 6 7
3 01 C 9 12
4 02 A 1 3
5 02 C 6 10
6 02 A 11 12
reproducible with: data <- data.frame(ID=c(rep("01",3),rep("02",3)), x=c("A","A","C","A","C","A"), t1=c(1,6,9,1,6,11), t2=c(4,7,12,3,10,12))
and I'd like to have data in this format:
ID t X
1 01 1 A
2 01 2 A
3 01 3 A
4 01 4 A
5 01 5 A
6 01 6 A
7 01 7 A
8 01 8 A
9 01 9 C
10 01 10 C
11 01 11 C
12 01 12 C
13 02 1 A
14 02 2 A
15 02 3 A
16 02 4 A
17 02 5 A
18 02 6 C
19 02 7 C
20 02 8 C
21 02 9 C
22 02 10 C
23 02 11 A
24 02 12 A
reproducible with: data_final <- data.frame(ID=c(rep("01",12),rep("02",12)), t = rep(1:12,2), x= c(rep("A",8),rep("C",4),rep("A",5),rep("C",5),rep("A",2))).
Mainly, I'd like to obtain a df (data_final) with one row for each t (for each ID), and the proper status X.
Any idea?
Related
I am working on chicken swarm optimization when the algorithm return the best solution the broker seem to have a different ordering
best solution
Cloudlet Vm
-------- ---------
99 1
52 2
62 7
63 13
64 3
68 14
71 6
94 0
97 8
13 9
53 10
91 11
16 12
1 4
61 5
15 15
33 16
34 17
35 18
43 19
44 1
45 2
46 7
47 13
49 3
42 14
48 6
50 0
51 8
37 9
40 10
36 11
39 12
41 4
38 5
6 15
31 16
19 17
65 18
88 19
89 1
66 2
9 7
92 13
93 3
18 14
98 6
14 0
30 8
12 9
2 10
96 11
11 12
29 4
77 5
87 15
70 16
76 17
78 18
81 19
82 1
69 2
56 7
57 13
32 3
85 14
75 6
80 0
83 8
60 9
86 10
79 11
74 12
84 4
67 5
28 15
90 16
27 17
21 18
72 19
95 1
73 2
26 7
23 13
25 3
24 14
3 6
20 0
59 8
58 9
0 10
55 11
54 12
4 4
22 5
17 15
8 16
10 17
7 18
5 19
printing the result after receiving from broker
Cloudlet ID STATUS Data center ID VM ID
99 SUCCESS 2 1
52 SUCCESS 2 2
62 SUCCESS 2 7
64 SUCCESS 2 3
71 SUCCESS 2 6
97 SUCCESS 2 8
63 SUCCESS 2 13
68 SUCCESS 2 14
94 SUCCESS 2 0
53 SUCCESS 2 10
13 SUCCESS 2 9
91 SUCCESS 2 11
16 SUCCESS 2 12
1 SUCCESS 2 4
61 SUCCESS 2 5
15 SUCCESS 2 15
35 SUCCESS 2 18
44 SUCCESS 2 1
33 SUCCESS 2 16
34 SUCCESS 2 17
45 SUCCESS 2 2
46 SUCCESS 2 7
49 SUCCESS 2 3
48 SUCCESS 2 6
51 SUCCESS 2 8
47 SUCCESS 2 13
42 SUCCESS 2 14
50 SUCCESS 2 0
43 SUCCESS 2 19
40 SUCCESS 2 10
37 SUCCESS 2 9
36 SUCCESS 2 11
39 SUCCESS 2 12
41 SUCCESS 2 4
38 SUCCESS 2 5
6 SUCCESS 2 15
31 SUCCESS 2 16
19 SUCCESS 2 17
65 SUCCESS 2 18
89 SUCCESS 2 1
88 SUCCESS 2 19
66 SUCCESS 2 2
9 SUCCESS 2 7
93 SUCCESS 2 3
92 SUCCESS 2 13
18 SUCCESS 2 14
98 SUCCESS 2 6
14 SUCCESS 2 0
30 SUCCESS 2 8
2 SUCCESS 2 10
12 SUCCESS 2 9
96 SUCCESS 2 11
any ideas why this this happened ?
(Edited 2021-09-06 13:30 CEST after I found out that the problem is caused at a different place of my code already)
I am working on some code (not my own) where they use a custom type for dynamic integer arrays. One instance of this type is passed via a common block between routines. It looks like this is not working properly or as expected, since the arrays take different values after being passed to a new routine. A minimal example looks like this:
implicit none
type intdynarr2
sequence
integer, pointer::i(:,:)
end type intdynarr2
type(intdynarr2):: my_array
integer j,k
common/carrays/my_array
allocate(my_array%i(1:10,1:10))
do j=1,10
do k=1,10
my_array%i(j,k)=j*k
enddo
enddo
write(*,*) my_array%i
call printarr
end
subroutine printarr
implicit none
type intdynarr2
sequence
integer, pointer::i(:,:)
end type intdynarr2
type(intdynarr2):: my_array
common/carrays/my_array
write(*,*) my_array%i
end subroutine
The output of this after compiling with gfortran in version 8.2.0 looks like this:
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100
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 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 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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
while I expected it to be:
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100
Can anyone tell me what is going wrong here and how to fix this?
I'm learning C and as a practice, I'm trying read a file with different sets of numbers in each line, and print (or save to a different file) each number per line (also as string).
You can see the code here:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 40
int main(){
char numbers[SIZE];
FILE *fileRead;
FILE *fileWrite;
char *token, *tofree, *str;
fileRead = fopen("/Users/USER/Documents/readfile.txt", "r");
if (fileRead==NULL){
printf("File not found\n");
return 1;
}
fileWrite = fopen("/Users/USER/Documents/writefile.txt", "w");
if (fileWrite==NULL){
printf("File not found\n");
return 1;
}
while (!feof(fileRead)){
fgets(numbers, SIZE, fileRead);
tofree = str = strdup(numbers);
while ((token = strsep(&str, " \n"))) fprintf(fileWrite,"%s\n", token);
free(tofree);
}
puts("Succeed");
return 0;
}
When I remove the '\n' character at printing/writing, all the numbers are printed one after the other. I expected that.
The problem is that when I include the \n char, the output includes some empty lines. I include an example of the input and the output files:
Input:
43 19 01 23 05 28 35
41 32 20 19 28 34 07
25 02 36 04 18 23 43
15 41 45 36 32 26 11
13 32 23 09 14 12 36
18 43 03 24 08 13 20
23 12 21 03 27 36 17
09 01 23 17 22 20 33
11 01 18 19 14 02
30 16 39 44 32 03
36 40 25 41 05 44
02 20 06 08 41 43
13
15
Output:
43
19
01
23
05
28
35
41
32
20
19
28
34
07
25
02
36
04
18
23
43
15
41
45
36
32
26
11
13
32
23
09
14
12
36
18
43
03
24
08
13
20
23
12
21
03
27
36
17
09
01
23
17
22
20
33
11
01
18
19
14
02
As you can see, the output includes an empt line when the original file had a newline, but if I remove the \n, it prints/writes just one number after other without space:
4319012305283541322019283407250236041823431541453632261113322309141236184303240813202312210327361709012317222033110118191402301639443203364025410544022006084143210219201733320528113826140803412735352236132117381233133230312645364405180322300236422806112726081307442523112145041827394426382243380510372504360104250602164226284117350617433404412518161910373624201317450344241202013435071104422329080106090526224243142223331215143012373820100331390117334234164401454327114125153130103225420930240137274114261206431112330135024321053027451435420809430807370327140127112337412506030824420320113615214544383436282305210401363805453529341319224405160121111525171338310322033738183632421824451732341905182302233945312133194425134030260524
What character is being inserted if \n is an explicit delimiter?
I have this vector:
a = [ 7 8 9 7 8 9];
and I would like to obtain the following vector:
b= [ 7 8 9 7 8 9;
17 18 19 17 18 19;
27 28 29 27 28 29;
37 38 39 37 38 39 ...]
I am replicating the vector and then summing 10 for each line (for n lines). I would like to do this without using loop iterations. How can I do it?
Thank you so much.
My first bsxfun solution.
a = [ 7 8 9 7 8 9];
b = 0:10:(10+10*n);
c = bsxfun(#plus,a,b.');
c =
7 8 9 7 8 9
17 18 19 17 18 19
27 28 29 27 28 29
37 38 39 37 38 39
47 48 49 47 48 49
57 58 59 57 58 59
67 68 69 67 68 69
77 78 79 77 78 79
87 88 89 87 88 89
97 98 99 97 98 99
107 108 109 107 108 109
Bit of explanation, though a full and complete introduction to bsxfun can be found in this answer by Divakar.
What happens is that your row array a gets piece-wise added to the column vector b. Thus the first element of a, being 7 in this case, gets added to the column vector b=[10;20;30;...] and becomes the first column of your output matrix c. The second entry of a is summed with the same column vector b and becomes the second column of c. This gets repeated to fill the entire matrix c to a size of numel(b) x numel(a).
This is becoming quite the coding fest. I ran some bench test, running a loop with n=1000 a hundred times and averaged the results. Windows 7, MATLAB R2012a, i5-750 CPU. Actually, the for loop is not even the worst in terms of timing:
bsxfun: 0.00003556 s.
repmat: 0.00048514 s.
cumsum: 0.00015726 s.
for : 0.00033096 s.
Timing revisited on the same system, but with MATLAB R2015a. for is now the slowest, with the others edging towards one another, but bsxfun prevails!
bsxfun: 0.00002030 s.
repmat: 0.00005213 s.
cumsum: 0.00002180 s.
for : 0.00019560 s.
Where I used this for loop implementation:
base = [7 8 9 7 8 9];
A = zeros(1e3,length(base));
for n = 1:1e3;
A(n,:) = base+10*n;
end
For completeness, you could also obtain the desired result through the use of the repmat command:
n = 3;
a = [7 8 9 7 8 9];
addingMatrix = repmat([0:10:10*n+1]',1,size(a,2));
b = addingMatrix + repmat(a,n+1,1);
Result:
b =
7 8 9 7 8 9
17 18 19 17 18 19
27 28 29 27 28 29
37 38 39 37 38 39
Since repmat and bsxfun are already taken, another approach is to create a temporary array where [7 8 9 7 8 9] is the first row, followed by a matrix completely full of 10s where the number of rows is the desired number you want and the number of columns is the total number of elements in the base vector ([7 8 9 7 8 9]). You'd then apply a cumulative sum via cumsum along the rows:
n = 11; %// Number of rows - including the first row of [7 8 9 7 8 9]
base = [7 8 9 7 8 9];
A = [base; 10*ones(n-1, numel(base))];
B = cumsum(A, 1);
We get:
>> B
B =
7 8 9 7 8 9
17 18 19 17 18 19
27 28 29 27 28 29
37 38 39 37 38 39
47 48 49 47 48 49
57 58 59 57 58 59
67 68 69 67 68 69
77 78 79 77 78 79
87 88 89 87 88 89
97 98 99 97 98 99
107 108 109 107 108 109
This code,
lineCount = 1;
do{ //find the line count in the file
c = fgetc(fp);
if(c == '\n') lineCount++;
}
while(c != EOF);
fclose(fp);
counts 6 lines from this file
5 7 9 3 2 10 1 11 6 4 14 0 12 8 13
3 4 10 8 0 12 13 2 7 1 9 5 6 14 11
12 14 11 8 0 7 3 5 1 6 4 13 10 9 2
14 11 13 0 2 12 9 3 5 7 1 6 8 4 10
0 1 8 6 5 3 11 2 7 9 4 12 10 14 13
and counts 5 lines from this file
39 47 37 30 7 38 17 49 11 1 29 41 25 19 10 45 23 0 32 15 2 9 4 6 21 40 20 24 5 31 34 3 33 48 44 27 14 26 28 35 16 42 46 36 12 8 22 13 18 43
37 13 24 28 34 27 5 41 36 29 44 26 0 15 40 31 23 35 9 8 4 33 21 6 11 49 2 7 43 32 16 1 30 42 39 14 45 10 38 22 19 17 20 25 18 47 48 46 3 12
0 49 26 20 14 12 10 3 9 23 15 37 5 32 4 42 25 46 38 45 40 19 22 1 39 29 7 41 33 13 30 35 11 6 18 31 21 28 24 36 16 43 27 34 44 17 2 8 47 48
0 1 20 11 28 3 43 9 15 25 45 29 33 19 48 18 17 16 14 34 10 7 42 4 37 41 22 30 23 21 32 39 2 46 8 36 40 27 31 13 6 38 12 5 44 26 35 24 49 47
15 30 18 7 34 25 43 14 38 48 40 9 33 26 28 27 21 0 20 10 47 8 11 32 12 5 36 4 46 42 6 29 13 31 23 17 39 35 19 49 24 41 44 16 37 45 2 1 22 3
What would the reason be?
EDIT
I created a file with 5 lines in Windows and 5 lines in Linux, Windows file counts 5 and Linux file counts 6. Why?
You should verify that the two files actually only have four newline characters. In Linux, use the xxd command to dump the contents of your files in hexadecimal and then count the number of a characters (because newline characters are the letter 'a' in hex):
$ cat foo.txt
5 7 9 3 2 10 1 11 6 4 14 0 12 8 13
3 4 10 8 0 12 13 2 7 1 9 5 6 14 11
12 14 11 8 0 7 3 5 1 6 4 13 10 9 2
14 11 13 0 2 12 9 3 5 7 1 6 8 4 10
0 1 8 6 5 3 11 2 7 9 4 12 10 14 13
$ xxd -p foo.txt
352037203920332032203130203120313120362034203134203020313220
38203133200a332034203130203820302031322031332032203720312039
20352036203134203131200a313220313420313120382030203720332035
20312036203420313320313020392032200a313420313120313320302032
20313220392033203520372031203620382034203130200a302031203820
362035203320313120322037203920342031322031302031342031330a <- note the 'a' at the end
$ xxd -p foo.txt | grep -o a | wc -l
5
You'll likely find that there are indeed five newline characters in your "6 line" file.
You start the count at 1 and increment for each newline encountered. If a file has one line—one string of non-newline characters followed by one newline—and then ends, you start the count at 1 and then increment it once, giving a line count of 2.
Perhaps want you want to do is start the count at 0, increment for each newline, and take note of any final non-newline-terminated-line? (That's a little bit harder.)
If test data were to be assumed to be the same as posted above and fp were to be opened as a text file:
I tested this on Linux and Windows. Both print 6(incorrect of-course because of the logic, which assumes that there is atleast 1 line)
gcc - 4.5.3
microsoft compiler cl for VS2010.
Also, linecount must start from 0 instead of 1.