How to get index number in a Boolean vector? For instance, my vector looks like this:
vector = (TRUE TRUE FALSE TRUE FALSE TRUE FALSE FALSE FALSE TRUE TRUE FALSE)
How to get index number for all TRUEs? vector["TRUE"] doesn't work.
Try using the which function (type ?which):
> my.vec <- c(TRUE, FALSE, FALSE, TRUE)
> which(my.vec)
> [1] 1 4
Related
Is there a function that will help me output all 2^n permutations of a boolean vector of length n? For instance, if i have a boolean vector of length n=2, c(FALSE,FALSE), i should obtain 2^2=4 permutations.
As such, I need a function, that will generalize this output for an array of length n,
that means if n=3, output should be of length 2^3 and so on...
I have already tried permutations from gtools package but this seems to be incorrect, or providing only a partial answer to say the least. This method does not generalize well and has given me errors for n>2 as well.
> permutations(2,2,c(TRUE,FALSE))
[,1] [,2]
[1,] FALSE TRUE
[2,] TRUE FALSE
Output should be:
FALSE, FALSE,
TRUE, TRUE,
FALSE, TRUE,
TRUE, FALSE
You where missing repeats.allowed=T :
gtools::permutations(2,2, c(T,F), repeats.allowed = T)
[,1] [,2]
[1,] FALSE FALSE
[2,] FALSE TRUE
[3,] TRUE FALSE
[4,] TRUE TRUE
You can make your custom function around permutations:
my_permute <- function(vect, n, repeats = TRUE) {
gtools::permutations(length(vect), n, vect, repeats.allowed = repeats)
}
my_permute(vect=c(T,F), n=2)
Example with more elements:
my_permute(letters[1:3], n=3)
You can use expand.grid,
expand.grid(c(TRUE, FALSE), c(TRUE, FALSE))
# Var1 Var2
#1 TRUE TRUE
#2 FALSE TRUE
#3 TRUE FALSE
#4 FALSE FALSE
You can use gtools package and the function permutations:
This is the source code:
library(gtools)
x <- c(TRUE, FALSE)
permutations(n=length(x),r=2,v=x,repeats.allowed=T)
Given logical vector x:
x <- c(FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE,
FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, TRUE)
How to split x based on every FALSE/TRUE patterns? Of course, we can simply do the split based on TRUE/FALSE patterns using !x.
So the split would search for the patterns FALSE, FALSE, ..., FALSE , TRUE, TRUE, ..., TRUE until we reach again a FALSE. At which point, we stop. Said differently, we do the split every time we move from a TRUE to a FALSE.
Here is what I ended up with:
p <- which(diff(x)==-1)+1
split(x, cumsum(seq_along(x) %in% p))
So the output is rightly:
# $`0`
# [1] FALSE FALSE FALSE TRUE TRUE
# $`1`
# [1] FALSE FALSE TRUE
# $`2`
# [1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE
# $`3`
# [1] FALSE TRUE
Any other solution to this problem? More efficient way to do this?
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
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
Suppose:
mu.iter <- c(3,3,3,3)
mu <- c(1,4,1,4)
> abs(mu.iter - mu) > 1.5
[1] TRUE FALSE TRUE FALSE
Instead of four TRUE/FALSE values, I just want one TRUE / FALSE value, such that it only returns TRUE when all 4 are TRUE and FALSE otherwise. The reason is that I want to put this into a while-loop.
Use all:
all(abs(mu.iter - mu) > 1.5)