how to convert a numeric vector into a time vector - r

in can r I have a numeric vector like c(15, 270, 540, 30, 15, 1440) representing minutes - but how can I create a vector out of this displaying hours and minutes?
Thanks in advance
Jasmin

This uses no packages and gives hours and minutes as asked (as opposed to days, hours and minutes).
x <- c(15, 270, 540, 30, 15, 1440)
sprintf("%02d:%02d", x %/% 60, x %% 60)
## [1] "00:15" "04:30" "09:00" "00:30" "00:15" "24:00"

Related

unique pairs or combinations from a vector

Where am I going wrong with my function.
I am trying to create a function which will count all the unique pairs in a vector, say I have the following input:
ar <- c(10, 20, 20, 30, 30, 30, 40, 50)
The number of unique pairs is 20 = 1, 30 = 1 so I can just sum these up and the total number of unique pairs is 2.
However everything I am trying is creating 30 as having 2 unique pairs (since 30 occurs 3 times in the vector.
n <- 9
ar <- c(10, 20, 20, 30, 30, 30, 40, 50)
CountThePairs <- function(n, ar){
for(i in 1:length(ar)){
sum = ar[i] - ar[]
pairs = length(which(sum == 0))
}
return(sum)
}
CountThePairs(n = NULL, ar)
Is there an easier way of doing this? I prefer the base R version but interested in package versions also.
Here's a simpler way using floor and table form base R -
ar <- c(10, 20, 20, 30, 30, 30, 40, 50)
sum(floor(table(ar)/2))
[1] 2
Example 2 - Adding one more 30 to vector so now there are 2 pairs of 30 -
ar <- c(10, 20, 20, 30, 30, 30, 30, 40, 50)
sum(floor(table(ar)/2))
[1] 3
If 2 30 pairs count as one "unique" pair then original solution by #tmfmnk was correct -
sum(table(ar) >= 2)
You could use sapply on the unique values of the vector to return a logical vector if that value is repeated. The sum of that logical value is then the number of unique pairs.
ar <- c(10, 20, 20, 30, 30, 30, 40, 50)
is_pair <- sapply(unique(ar), function(x) length(ar[ar == x]) > 1)
sum(is_pair)
#[1] 2
I'm not sure what behaviour you want if there are four 30's - does this count as one unique pair still or is it now two? If the latter, you would need a slightly different solution:
n_pair <- sapply(unique(ar), function(x) length(ar[ar == x]) %/% 2)
sum(n_pair)
#[1] 2

Is there any way to undertake rounding with custom rules?

I'm wondering if there's any way to round up or down based on my own rules, not just the basic 0.5 up or down.
The numbers I'm trying to round are in the form of 24 hour time i.e. 2250, 1100, 830 (but in numeric format), and I want to round up or down based on if the last two numbers are above or below 30 - and this is rounding up to the next hour.
Any help would be appreciated, thank you.
You could just offset the numbers before rounding them :
round(c(2250, 1100, 830) + 20, -2)
# [1] 2300 1100 800
You might want to add %% 2400 to it :
round(2350 + 20, -2)
# [1] 2400
round(2350 + 20, -2) %% 2400
# [1] 0
So that would be :
round_hour <- function(x) round(x + 20, -2) %% 2400
Thanks #snoram for the tip
Something along the line of this?
# Function
hround <- function(x) {
if (any(x < 0 | x > 24000)) stop("Invalid format")
mins <- x %% 100
x <- x - mins + ifelse(mins >= 30, 100, 0)
ifelse(x == 2400, 0, x)
}
# test data:
test <- c(2250, 1100, 830, 725)
# Test run
hround(test)
# [1] 2300 1100 900 700

R - sequence with increasing interval

normal sequences with fixed intervals can be created using seq(from, to, by= )
is there a way to create a sequence with increasing intervals like the sequence below.
seq1 = c(2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192)
here each of vector element is 2^index
We can just use
## not `2 ^ 1:13`
2 ^ (1:13)
or
2 ^ seq(1, 13, 1)

R Programming - convert numeric to MM:SS

This may be a silly question, but I can't find anything on this.
I have a numeric value that represents seconds. How can I convert it to MM:SS
For example
My number is 96
Represented in MM:SS it should be 01:36.
Any help is appreciated.
The %/% (integer division) and %% (modulo) operators are your friends:
x <- 96
paste(x %/% 60, x %% 60, sep = ":")
which gives
> paste(x %/% 60, x %% 60, sep = ":")
[1] "1:36"
Here it is in a function:
d2ms <- function(x) {
paste(x %/% 60, x %% 60, sep = ":")
}
> xx <- c(120, 96, 45, 30)
> d2ms(xx)
[1] "2:0" "1:36" "0:45" "0:30"
Which shows we need a little help to get exactly the format you need; see ?sprint for ways to format numbers [as characters] with leading 0s etc:
d2ms <- function(x) {
sprintf("%02d:%02d", x %/%60, x %% 60)
}
> d2ms(xx)
[1] "02:00" "01:36" "00:45" "00:30"
Note that the : in the string above is a literal, the %xxy bits are the formats for the values specified in the next two arguments and include formatting details for the number of zeros to pad (i.e. pad with zeroes until number uses two digits.) The template for this usage here is:
%[flag][width]specifier,
where here we used:
0 as the flag --- pad with 0s
width was 2, we want MM or SS
specifier was d for integers (could also have been i)
Whether you need that or not is up to your end use case.
These operators are quite useful for these sorts of operations; another example would be converting from degrees, minutes, seconds notation to decimal degrees for spatial coordinates.
Try:
x<-96
sprintf("%02d:%02d",x%/%60,x%%60)
#[1] "01:36"

R: Average nearby elements in a vector

I have many vectors such as this: c(28, 30, 50, 55, 99, 102) and I would like to obtain a new vector where elements differing less than 10 from one to another are averaged. In this case, I would like to obtain c(29, 52.5, 100.5).
Another way
vec <- c(28, 30, 50, 55, 99, 102)
indx <- cumsum(c(0, diff(vec)) > 10)
tapply(vec, indx, mean)
# 0 1 2
# 29.0 52.5 100.5

Resources