how to do for-loop in R - r

aa <-order(maxstaCode$ gateInComingCnt,decreasing=TRUE)[1:10]
aa
[1] 11 121 19 79 13 21 43 10 15 138
for(i in aa){
maxinnum<-c(maxstaCode$gateInComingCnt[i])
}
maxinum
I wanted to use the loop to bring the numbers of aa into the index value in the chart in sequence, and runs out of the value corresponding to the index value the result below
[1] 6235770 2805043 2772432 2592227 2461369 2428441 1990890 1821025 1595055
[10] 1491299
but it turned out:
[1] 1491299

In the for loop, the issue was that maxinum is updated on each iteration, resulting in returning the last value. Instead we need to use c(maxinum, ...)
maxinum <- c()
for(i in aa){
maxinum <- c(maxinum, maxstaCode$gateInComingCnt[i])
}
maxinum

Related

drawing a value from a vector r

After removing the values from the vector from 1 to 100 I have the following vector:
w
[1] 2 5 13 23 24 39 41 47 48 51 52 58 61 62 70 71 72 90
I am now trying to draw values from this vector with the sample function
for(x in roznica)
{
if(licznik_2 != licznik_1 )
{
roznica_proces_2 <- sample(1:w, roznica)
} else {
roznica_proces_2 <- NA
}
}
I tried various combinations with the sample
If w is the name of the vector then you would NOT use sample(1:w, ...). For one thing 1:w doesn't really amke sense since the : operator expects its second argument to be a single number, while w is apparently on the order of 15 values. Depending on what roznica is (and hopefully it is a single integer) then you might use:
sample(w, roznica) # returns a vector of length roznica's value of randomly ordered values in `w`.
The other problem is that you are currently overwirign any values from prior iterations of the for loop. So you might want to use:
roznica_proces_2[roznica] <- sample(1:w, roznica)
You would of course need to have initialized roznica_proces_2, perhaps with:
roznica_proces_2 <- list()
Regarding your query in the comment :
I am only concerned with the sample function itself: I will show an example : w [1] 31 and now I want to draw 1 number from that in ( which is 31) proces_nr_2 <- sample(w, 1) What does he get? proces_nr_2 [1] 26
The reason that happens is because when a vector is of length 1 the sampling takes from 1 to that number. It is explained in the help page of ?sample.
If x has length 1, is numeric (in the sense of is.numeric) and x >= 1, sampling via sample takes place from 1:x
So if you have only 1 number to sample just return that number directly instead of passing it in sample.

R Programming find the first entry in a list bigger than

Suppose that we have the table x:
V1 V2 V3
1 8 18
95 36 -40
-67 -68 -27
192 2 9
160 105 36
I want to find the 1st row from the V1, which is bigger than 100. In our case the 192 is the 1st bigger number than 100. So i want to get 4 as an output, because 192 is the 4th row in V1.
How can I achieve this? I tried this:
for (i in 1:length(x$v1){
if(x[1,i]>=100){
print(i)
break}
}
But it didn't work. The R compiler says this:
Error in if (x[1, i] >= 100) print(i) : argument is of length zero
> break
Error: no loop for break/next, jumping to top level
> }
Error: unexpected '}' in "}"
What can I do?
We can get the column index of the first entry in each row with max.col
j1 = max.col(df1 > 100, 'first')
j2 = j1 * NA^!rowSums(df1 > 100)
Then extract the value with row/column indexing
na.omit(df1[cbind(seq_len(nrow(df1)), j2)])[1]
#[1] 192
If we are only checking the first column, which.max can be used
which.max(df1$V1 > 100)
Change your loop with:
for (i in 1:length(df[,1])){
if(df[i,1]>=100){
print(i)
break}
}

How do I Compute Binary String Permutations in R?

I have a binary string like this:
0010000
I'd like to have all these permutations:
1010000
0110000
0011000
0010100
0010010
0010001
Is there anybody know which function in R could give me these results?
R has functions for bitwise operations, so we can get the desired numbers with bitwOr:
bitwOr(16, 2^(6:0))
#> [1] 80 48 16 24 20 18 17
...or if we want to exclude the original,
setdiff(bitwOr(16, 2^(6:0)), 16)
#> [1] 80 48 24 20 18 17
However, it only works in decimal, not binary. That's ok, though; we can build some conversion functions:
bin_to_int <- function(bin){
vapply(strsplit(bin, ''),
function(x){sum(as.integer(x) * 2 ^ seq(length(x) - 1, 0))},
numeric(1))
}
int_to_bin <- function(int, bits = 32){
vapply(int,
function(x){paste(as.integer(rev(head(intToBits(x), bits))), collapse = '')},
character(1))
}
Now:
input <- bin_to_int('0010000')
output <- setdiff(bitwOr(input, 2^(6:0)),
input)
output
#> [1] 80 48 24 20 18 17
int_to_bin(output, bits = 7)
#> [1] "1010000" "0110000" "0011000" "0010100" "0010010" "0010001"
library(stringr)
bin <- '0010000'
ones <- str_locate_all(bin, '1')[[1]][,1]
zeros <- (1:str_length(bin))[-ones]
sapply(zeros, function(x){
str_sub(bin, x, x) <- '1'
bin
})
[1] "1010000" "0110000" "0011000" "0010100" "0010010" "0010001"
We assume that the problem is to successively replace each 0 in the input with a 1 for an input string of 0's and 1's.
Replace each character successively with a "1", regardless of its value and then remove any components of the result equal to the input. No packages are used.
input <- "0010000"
setdiff(sapply(1:nchar(input), function(i) `substr<-`(input, i, i, "1")), input)
## [1] "1010000" "0110000" "0011000" "0010100" "0010010" "0010001"
Update: Have completely revised answer.

Read integers from binary <8 bits in R

In R, I am trying to convert binary data to integer values, but instead of 1 value being stored in 1 byte, multiple values are stored within and across bytes.
I know there are 12 integer values stored across 64 bits (8 bytes). The 12 integers have the following bit count: 5,6,5,5,4,7,5,6,5,5,4,7
After the following code:
time <- readBin(fid,integer(),size=1,n=8,signed='FALSE')
The return is:
[1] 25 156 113 63 214 158 113 63
The correct data should be:
25 32 19 17 11 31 22 54 19 17 11 31
I have tried using bitAnd and bitShiftL (package bitops), but have had no real success. And help would be greatly appreciated.
Note that the operation on each 4-byte integer is the same (the pattern is repeated twice). Thus, it suffices to solve the problem for a 4-byte integer, and loop over the 4-byte integers in the file (retrieved via readBin). This is much simpler than considering the problem byte-by-byte.
# length(x) should be 1
bitint <- function(x, bitlens) {
result <- integer(length(bitlens))
for (i in seq_along(bitlens)) {
result[i] <- bitwAnd(x, (2^bitlens[i])-1)
x <- bitwShiftR(x, bitlens[i])
}
return(result)
}
bitlens <- c(5,6,5,5,4,7)
x <- c(1064410137L, 1064410838L)
c(sapply(x, function(i) bitint(i, bitlens)))
## [1] 25 32 19 17 11 31 22 54 19 17 11 31
I don't know of a clean elegant way to do this with the standard data reading base functions (function like redBin seems to prefer to no less than a byte at a time). So i've created a function that does some of the messy calculations to extract bits from bytes and turn them into numbers. I did end up using the bitwise operators in base R (see ?bitwAnd) Here's the function
bitints <- function(bytes, bitlengths) {
stopifnot(sum(bitlengths) <= 8*length(bytes))
stopifnot(all(bitlengths <= 8))
bytebits <- rep.int(8, length(bytes))
masks <- c(1L,3L,7L,15L,31L,63L,127L, 255L)
outs <- numeric(length(bitlengths))
for(i in seq_along(bitlengths)) {
need <- bitlengths[i]
got <- 0
r <- 0
while(need>0) {
j <- which(bytebits>0)[1]
bitget <- min(need, bytebits[j])
r <- r + bitwShiftL(bitwAnd(bytes[j],masks[bitget]), got)
bytebits[j] = bytebits[j]-bitget
bytes[j] = bitwShiftR(bytes[j], bitget)
need <- need - bitget
got <- got + bitget
}
outs[i] <- r
}
outs
}
You just pass in your array of byte values and your array of bit sizes to get the values you need. Here's an example using your data.
bytes <- c(25L, 156L, 113L, 63L, 214L, 158L, 113L, 63L)
bitlens <- c(5,6,5,5,4,7,5,6,5,5,4,7)
bitints( bytes, c(5,6,5,5,4,7,5,6,5,5,4,7) )
# [1] 25 32 19 17 11 31 22 54 19 17 11 31
Note that I had to change around some of your bit lengths to get the values you were expecting. You might want to double check that you either had the expected output correct or that your bit lengths were correct.

How to sum specific vectors in a list in R

I know this should be simple but I just can't do it...I have a data frame called data that works nicely and does what I want it to with the correct column headers and everything. I can call colSums() to get a list of 21 numbers which are the sums of each column.
> a <- colSums(data,na.rm = TRUE)
> names(a) <- NULL
> a
[1] 1000000.00 680000.00 170000.00 462400.00 115600.00 144500.00 314432.00 78608.00 98260.00 122825.00 213813.76 53453.44 66816.80
[14] 83521.00 104401.25 145393.36 36348.34 45435.42 56794.28 70992.85 88741.06
The problem is I need a list with the first number alone, the sum of the next two, sum of the next 3, sum of the next 4 etc. until I run out of numbers. I imagine it would look something like this:
c(sum(a[1]),sum(a[2:3]),sum(a[4:6])... etc.
Any help or a different way to do this would be greatly appreciated!
Thank you.
You should only need to go out to something on the order of sqrt(length(vector)). The seq function lets you specify a start integer and a length, so sending a sequence of integers to seq(1+x*(x-1)/2, length=x) should create the right set of sequences. It wasn't clear whether incomplete sequences at the end should return a result or NA so I put in na.rm=TRUE. You might decide otherwise. (You did not illustrate a dataframe but rather an ordinary numeric vector.
sumsegs <- function(vec) sapply(1:sqrt(2*length(vec)), function(x)
sum( vec[seq(1+x*(x-1)/2, length=x)], na.rm=TRUE) )
a <- scan()
1000000.00 680000.00 170000.00 462400.00 115600.00 144500.00 314432.00 78608.00 98260.00 122825.00 213813.76 53453.44 66816.80 83521.00 104401.25 145393.36 36348.34 45435.42 56794.28 70992.85 88741.06
# 22: enter carriage return to stop scan input
#Read 21 items
sumsegs(a)
#[1] 1000000.0 850000.0 722500.0 614125.0 522006.2 443705.3
I'm not exactly sure what the right upper limit on the number to send to the inner function. sqrt(length(vec)) is too short, but sqrt(2*length(vec)) seems to be "working" at lower numbers anyway.
> sapply( sapply(1:sqrt(2*100), function(x) seq(1+x*(x-1)/2, length=x) ), max)
[1] 1 3 6 10 15 21 28 36 45 55 66 78 91 105
> sapply( sapply(1:sqrt(100), function(x) seq(1+x*(x-1)/2, length=x) ), max)
[1] 1 3 6 10 15 21 28 36 45 55
This is a function that returns the last element in sequences so formed and making the factor 2.1 rather than 2 corrects minor deficiencies in the range of length 500-1000:
tail(lapply( sapply(1:sqrt(2.1*500), function(x) seq(1+x*(x-1)/2, length=x) ), max),1 )
[[1]]
[1] 528
tail(lapply( sapply(1:sqrt(2.1*500), function(x) seq(1+x*(x-1)/2, length=x) ), max),1 )
[[1]]
[1] 496
Going higher did not seem to degrade the "times 2" correction. There's probably some kewl number theory explanation for this.
tail(lapply( sapply(1:sqrt(2*100000), function(x) seq(1+x*(x-1)/2, length=x) ), max),1 )
[[1]]
[1] 100128
Alternatively a much more naive method is:
sums=colSums(data)
n=0 # number of sums
i=1 # currentIndex
intermediate=0;
newIndex=1;
newVec <- vector()
while(i<length(sums)) {
for(j in i:(i+n)) {
if(j<=length(sums))
intermediate=intermediate+sums[j]
}
if(n>1){
i=i+n+1;
}
else{
i=i+1;
}
newVec=c(newVec, intermediate);
intermediate=0;
n=n+1;
}
Here's a similar approach, using rep(...) and by(...)
n <- (-1+sqrt(1+8*length(a)))/2 # number of groups
groups <- rep(1:n,1:n) # indexing vector
result <- as.vector(by(a,groups,sum))
result
# [1] 1000000.0 850000.0 722500.0 614125.0 522006.2 443705.3

Resources