applying function to a vector - r

I have a set of dates (as.Date from RQuantLib) stored as a list or row in my_dates
I would like to select the first value for which this condition is true
businessDaysBetween("UnitedStates", TodayDate, my_dates)>10
where TodayDate<-as.Date(format(Sys.time(), "%Y%m%d"), "%Y%m%d") is today date.
Thank you.

This can be very simple, if you want only the values or the first value.
A conditional statement applied to a vector results in a true/false vector
A true/false vector can be used as an index to a vector, and returns a shorter vector of the values where the condition is true.
Example: Initialize x to contain 10 random numbers. Is each one bigger than 0.7? Now return those that are bigger than 0.7. Then return the first one.
x = rnorm(10)
x
[1] -0.96029244 0.41779224 0.08058894 -0.02026729 -0.65383370 -0.83572926
[7] 0.92722221 0.49157700 0.88779718 -1.09073923
x>0.7
[1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE TRUE FALSE
x[x>0.7]
[1] 0.9272222 0.8877972
first one...
x[x>0.7][1]
[1] 0.9272222

Use which on the result of your businessDaysBetween call.
set.seed(21)
my_dates <- Sys.Date()+sample(50,10)
bizday_gt10 <- sapply(my_dates, businessDaysBetween,
calendar="UnitedStates", from=Sys.Date()) > 10
if(any(bizday_gt10)) {
first_bizday_gt10 <- which(bizday_gt10)[1]
my_dates[first_bizday_gt10]
} else {
stop("no business days between today and today+10")
}
Note that you need to check that there's at least 1 TRUE observation in bizday_gt10, else which will return a zero-length vector.

Related

R function returning boolean of which element in vector is maximum

I need a boolean that tells me whether an element of a vector is that vector's maximum. Should return something like this
vec <- c(3,4,1,5)
maxBoolFunct(vec)
[1] FALSE FALSE FALSE TRUE
max() just tells me what the maximum value actually is and which.max simply gives me the position in the vector. I need a boolean.
You can use logical indexing.
> vec = c(3,4,1,5)
> vec == max(vec)
[1] FALSE FALSE FALSE TRUE

Why does rlang::quo_is_missing(quo(NA)) evaluate to FALSE?

If I understand, rlang::quo_is_missing evaluates a quosure and checks whether it contains a missing value. If it does, it should return TRUE, FALSE if not. Yet, I've tried the following combinations and it always returns FALSE:
rlang::quo_is_missing(quo(NA))
rlang::quo_is_missing(quo(NA_character_))
rlang::quo_is_missing(quo(NA_integer_))
If I try non-NA values, it also returns FALSE, as expected:
rlang::quo_is_missing(quo("hello"))
Why is it returning FALSE when the value is obviously missing?
"Missing" is a special term that refers to values that are not present at all. NA is not the same as "missing" -- NA is itself a value. In base R you can compare the functions is.na() and missing() each of which do different things. quo_is_missing is like the missing() function, not is.na and returns true only when there is no value at all:
rlang::quo_is_missing(quo())
If you want to check for NA, you could write a helper
quo_is_na <- function(x) {
!rlang::quo_is_symbolic(x) &&
!rlang::quo_is_missing(x) &&
!rlang::quo_is_null(x) &&
is.na(rlang::quo_get_expr(x))
}
quo_is_na(quo())
# [1] FALSE
quo_is_na(quo(x+y))
# [1] FALSE
quo_is_na(quo(NULL))
# [1] FALSE
quo_is_na(quo(42))
# [1] FALSE
quo_is_na(quo(NA))
# [1] TRUE
quo_is_na(quo(NA_character_))
# [1] TRUE

Remove the numbers < 4 digits in list in a data frame in R

I have a data frame like this this, i need to remove the values less than 4 digits in the item column,
department item
xyz009 c("1","676547","2","434567","3","567369","4","987654","6","54546676732")
Output
department item
xyz009 676547,434567,567369,987654,54546676732
Thank you for your help
Maybe you can try nchar+subset
> subset(v,nchar(v)>4)
[1] "676547" "434567" "567369"
[4] "987654" "54546676732"
DATA
v <- c("1","676547","2","434567","3","567369","4","987654","6","54546676732")
1.Create a minimal reproducible example
xyz009 <- c("1","676547","2","434567","3","567369","4","987654","6","54546676732")
2.Suggested solution using base R:
The vector xyz009 is of type character
typeof(xyz009)
[1] "character"
In order to do maths with it (i.e. use >) we have to cast it to numeric using as.numeric
num_xyz <- as.numeric(xyz009)
Now we can use an index to 'filter' values where an expression evaluates to TRUE:
test_result <- num_xyz > 9999
The vector test_result consists of booleans
test_result
[1] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
We can use these booleans as an 'index' (R keeps only values where the index is TRUE):
num_xyz[test_result]
This returns:
[1] 676547 434567 567369 987654 54546676732
Using base R you can use unlist, and lapply:
xyz009<-c("1","676547","2","434567","3","567369","4","987654","6","54546676732")
unlist(lapply(xyz009,function(x) x[nchar(x)>3]))
The result is:
[1] "676547" "434567" "567369" "987654" "54546676732"

How to check if an element exist in a vector when the element may be NULL using base r functions

Assume we have a vector and want to check if a variable is part of that vector. This is going to be used in a function as a error handling and the input can also be NULL
values <- c("ALL", "NON")
parameter <- "ALL"
the easy solution is to use is.element() or %in% but the parameter can be NULL and in that case we get an error in if()
parameter <- NULL
is.element(parameter, values)
logical(0)
if(is.element(parameter, values)){stop("invalid parameter")}
Error in if (is.element(parameter, values)) { :
argument is of length zero
If you want to use %in% you can reverse the call and use any on top :
any(c("ALL", "NON") %in% NULL) # [1] FALSE
c("ALL", "NON") %in% NULL returns a logical of length 2 so we need anyto get the output.
Another possibility is to use purrr::has_element, which handles this case :
library(purrr)
has_element(c("ALL", "NON"), NULL) # [1] FALSE
It's also stricter :
has_element(1, "1") # [1] FALSE
is.elements(1, "1") # [1] TRUE
has_element(list(iris), list(as.list(iris))) # [1] FALSE
is.element(list(iris), list(as.list(iris))) # [1] TRUE
There are multiple ways to check. The exact function to check is is.null which returns TRUE if it is NULL
!is.null(parameter) && is.element(parameter, values)
Other option is length which returns 0 for NULL
length(parameter) > 0 && is.element(parameter, values)
NOTE: Both the methods evaluate the second argument only if the first condition is TRUE. So it will return FALSE whenever 'parameter' is NULL. We can evaluate this in the same argument order as in the OP's is.element as
1:3 %in% 2
#[1] FALSE TRUE FALSE
2 %in% 1:3
#[1] TRUE
returns different results.
NOTE: No packages used and here we assume that the OP pass vectors of same type

Determine if a vector is ordered

I would like to determine if a vector is either always increasing or always decreasing in R.
Ideally, if I had these three vectors:
asc=c(1,2,3,4,5)
des=c(5,4,3,2,1)
non=c(1,3,5,4,2)
I would hope that the first two would return TRUE, and the last would return FALSE.
I tried a few approaches. First, I tried:
> is.ordered(asc)
[1] FALSE
> is.ordered(des)
[1] FALSE
> is.ordered(non)
[1] FALSE
And I also tried:
> order(non)
[1] 1 5 2 4 3
And hoped that I could simply compare this vector with 1,2,3,4,5 and 5,4,3,2,1, but even that returns a string of logicals, rather than a single true or false:
> order(non)==c(1,2,3,4,5)
[1] TRUE FALSE FALSE TRUE FALSE
Maybe is.unsorted is the function your looking for
> is.unsorted(asc)
[1] FALSE
> is.unsorted(rev(des)) # here you need 'rev'
[1] FALSE
> is.unsorted(non)
[1] TRUE
From the Description of is.unsorted you can find:
Test if an object is not sorted (in increasing order), without the cost of sorting it.
Here's one way using ?is.unsorted:
is.sorted <- function(x, ...) {
!is.unsorted(x, ...) | !is.unsorted(rev(x), ...)
}
Have a look at the additional arguments to is.unsorted, which can be passed here as well.
Here is one way without is.unsorted() to check if to vectors are sorted. This function will return true, if all elements in the vector given are sorted in an ascending manner or false if not:
is.sorted <- function(x) {
if(all(sort(x, decreasing = FALSE) == x)) {
return(TRUE)
} else {
return(FALSE)
}
}

Resources