Get all boolean comparisons from vectors with different lengths in R - r

I've two vectors with different lengths and want to get all the occurrences of the first one in the second one.
I've tried:
vec <- c("jan-fev-mar", "abr-mai-jun", "jul-ago-set")
vec2 <- c("jan-fev-mar", "abr-mai-jun", "jul-ago-set", "out-nov-dez", "jan-fev-mar", "abr-mai-jun", "jul-ago-set", "out-nov-dez")
# It returns: TRUE TRUE TRUE
vec %in% vec2
I expect to get all the occurrences of vec on vec2, like: TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE

vec %in% vec2 returns TRUE for each element in vec if there is a match in all elements of vec2. The result is a logical vector of length equal to length(vec).
It seems you want vec2 %in% vec, which returns:
vec2 %in% vec
[1] TRUE TRUE TRUE FALSE TRUE TRUE TRUE FALSE
You could interpret it like the following:
(vec2 %in% vec)[1]: There is a match of vec2[1] (= "jan-fev-mar") in vec? TRUE
(vec2 %in% vec)[2]: There is a match of vec2[2] (= "abr-mai-jun") in vec? TRUE
...
(vec2 %in% vec)[8]: There is a match of vec2[8] (= "out-nov-dez") in vec? FALSE

Related

How can I change values froma vector with a previous condition?

I have a logical vector
vector1 <- c(F,F,T,F,F)
and I want to create a vector2 with the same values as vector1 but when vector1[i] == TRUE vector2[i-1], vector2[i] and vector2[i+1] has to be also TRUE.
What is the best way to do this? the ideal would be to create a function also since I will have to this for many other vectors...
One way using boolean comparison is:
c(vector1[-1], FALSE) | vector1 | c(FALSE, vector1[-length(vector1)])
Value is TRUE at a position if the preceding is TRUE, or the position is TRUE or the next position is TRUE. First and last values are boundaries and have no preceding or next values, that is why positions are completed by FALSE.
For more than one position, here two:
lag <- 2
c(vector1[-(1:lag)], rep(FALSE, lag)) | vector1 | c(rep(FALSE, lag), vector1[-(length(vector1)-lag+1:length(vector1))])
[1] TRUE FALSE TRUE FALSE TRUE
You can also try dplyr:
case_when(lead(vector1) ~ TRUE,
lag(vector1) ~ TRUE,
TRUE ~ vector1)
[1] FALSE TRUE TRUE TRUE FALSE
You can do :
#Copy vector1 elements
vector2 <- vector1
#Get indices where vector has TRUE elements
inds <- which(vector2)
#Get +1 and -1 position of each TRUE value
inds1 <- unique(c(inds + 1, inds - 1))
#Remove values which are out of range
inds1 <- inds1[inds1 <= length(vector2) & inds1 >= 1]
#Assign TRUE values
vector2[inds1] <- TRUE
vector2
#[1] FALSE TRUE TRUE TRUE FALSE

How to return a Boolean vector that tells whether element in vector A is in vector B?

Suppose I have two vectors, A and B. I want to get a boolean vector with the same length of vector A, which tells the information of each element in vector A whether it is in vector B. What is the function for it?
I think you're looking for %in%:
A <- c(0,2,4,6)
B <- c(8,7,6,5,4)
A %in% B
[1] FALSE FALSE TRUE TRUE
A <- c(0,2,4,6)
B <- c(8,7,6,5,4)
x <- (is.element(A, B))
x
## [1] FALSE FALSE TRUE TRUE

does vector exist in matrix?

how can I check to see if vector exists inside a matrix. The vector will be of size 2. I have an approach but I would like something vectorized/faster.
dim(m)
[1] 30 2
x = c(1, -2)
for(j in 1:nrow(m)){
if ( isTRUE(as.vector(x[1]) == as.vector(m[j,1])) && as.vector(x[2] == as.vector(m[j,2]) )) {
print(TRUE)
}
}
note, x=c(1, -2) is not the same as -2, 1 in the matrix.
If we are comparing the rows of the matrix ('m') with 'x' having the same length as the number of columns of 'm', we can replicate 'x' (x[col(m)]) to make the lengths same, compare (!=), get the rowSums. If the sum is 0 for a particular row, it means that all the values in the vector matches that row of 'm'. Negate (!) to convert 0 to TRUE and all other values as FALSE.
indx1 <- !rowSums(m!=x[col(m)])
Or if we need a solution using apply, we can use identical
indx2 <- apply(m, 1, identical, y=x)
identical(indx1, indx2)
#[1] TRUE
If this to find only a single TRUE/FALSE, we can wrap any to 'indx1' or 'indx2'.
data
x <- c(1, -2)
set.seed(24)
m <- matrix(sample(c(1,-2,3,4), 30*2, replace=TRUE), ncol=2)
Try
m<-matrix(rnorm(60),30)
x<-m[8,]
m[9,]<-c(x[2],x[1]) # to prove 1,-2 not same -2,1
apply(m,1,function(n,x) all(n==x),x=x)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[24] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
if you need just one T/F use any() you
any(apply(m,1,function(n,x) all(n==x),x=x))
[1] TRUE
if run this code with akrun's data
x <- c(1, -2)
set.seed(24)
m <- matrix(sample(c(1,-2,3,4), 30*2, replace=TRUE), ncol=2)
any(apply(m,1,function(n,x) all(n==x),x=x))
[1] TRUE

Trouble determining use of & in this function

A friend wrote up this function for determining unique members of a vector. I can't figure out (mentally) what this one line is doing and it's the crux of the function. Any help is greatly appreciated
myUniq <- function(x){
len = length(x) # getting the length of the argument
logical = rep(T, len) # creating a vector of logicals as long as the arg, populating with true
for(i in 1:len){ # for i -> length of the argument
logical = logical & x != x[i] # logical vector = logical vector & arg vector where arg vector != x[i] ??????
logical[i] = T
}
x[logical]
}
This line I can't figure out:
logical = logical & x != x[i]
can anyone explain it to me?
Thanks,
Tom
logical is a vector, I presume a logical one containing len values TRUE. x is a vector of some other data of the same length.
The second part x != x[i] is creating a logical vector with TRUE where elements of x aren't the same as the current value of x for this iteration, and FALSE otherwise.
As a result, both sides of & are now logical vector. & is an element-wise AND comparison the result of this is TRUE if elements of logical and x != x[i] are both TRUE and FALSE otherwise. Hence, after the first iteration, logical gets changed to a logical vector with TRUE for all elements x not the same as the i=1th element of x, and FALSE if they are the same.
Here is a bit of an example:
logical <- rep(TRUE, 10)
set.seed(1)
x <- sample(letters[1:4], 10, replace = TRUE)
> x
[1] "b" "b" "c" "d" "a" "d" "d" "c" "c" "a"
> logical
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> x != x[1]
[1] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> logical & x != x[1]
[1] FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
This seems very complex. Do you get the same results as:
unique(x)
gives you? If I run my x above through myUniq() and unique() I get the same output:
> myUniq(x)
[1] "b" "d" "c" "a"
> unique(x)
[1] "b" "c" "d" "a"
(well, except for the ordering...)

which rows match a given vector in R

I have a matrix A,
A = as.matrix(data.frame(col1 = c(1,1,2,3,1,2), col2 = c(-1,-1,-2,-3,-1,-2), col3 = c(2,6,1,3,2,4)))
And I have a vector v,
v = c(-1, 2)
How can I get a vector of TRUE/FALSE that compares the last two columns of the matrix and returns TRUE if the last two columns match the vector, or false if they don't?
I.e., If I try,
A[,c(2:3)] == v
I obtain,
col2 col3
[1,] TRUE FALSE
[2,] FALSE FALSE
[3,] FALSE FALSE
[4,] FALSE FALSE
[5,] TRUE FALSE
[6,] FALSE FALSE
Which is not what I want, I want both columns to be the same as vector v, more like,
result = c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE)
Since the first, and 5th rows match the vector v entirely.
Here's a simple alternative
> apply(A[, 2:3], 1, function(x) all(x==v))
[1] TRUE FALSE FALSE FALSE TRUE FALSE
Ooops by looking into R mailing list I found an answer: https://stat.ethz.ch/pipermail/r-help/2010-September/254096.html,
check.equal <- function(x, y)
{
isTRUE(all.equal(y, x, check.attributes=FALSE))
}
result = apply(A[,c(2:3)], 1, check.equal, y=v)
Not sure I need to define a function and do all that, maybe there are easier ways to do it.
Here's another straightforward option:
which(duplicated(rbind(A[, 2:3], v), fromLast=TRUE))
# [1] 1 5
results <- rep(FALSE, nrow(A))
results[which(duplicated(rbind(A[, 2:3], v), fromLast=TRUE))] <- TRUE
results
# [1] TRUE FALSE FALSE FALSE TRUE FALSE
Alternatively, as one line:
duplicated(rbind(A[, 2:3], v), fromLast=TRUE)[-(nrow(A)+1)]
# [1] TRUE FALSE FALSE FALSE TRUE FALSE
A dirty one:
result <- c()
for(n in 1:nrow(A)){result[n] <-(sum(A[n,-1]==v)==2)}
> result
[1] TRUE FALSE FALSE FALSE TRUE FALSE

Resources