Logical Comparison of Two Vectors with Binary (0/1) Result

Logical comparison of two vectors with binary (0/1) result

You can use the ifelse function:

r1 <- ifelse(p >= u, 1, 0)

Or you can simply convert the logical comparison into a numeric vector, which turns TRUE into 1 and FALSE into 0:

r1 <- as.numeric(p >= u)

Compare two vectors

 DF$V3 <- ifelse(DF$V2 <= DF$V1-8, 1, 0)
DF
# V1 V2 V3
# 1 10 2 1
# 2 20 29 0
# 3 30 21 1
# 4 40 60 0

What is the logic behind binary comparison between elements and number of elements in finding a subset?

Assign each element in the set a different power of two (1, 2, 4, 8, etc.) as an ID. Each subset is a combination of various elements in the set, which can be represented by combinations of the IDs. Adding up the IDs in a subset will give a unique number.

This can also be worked in reverse: every number from 0 to 2n-1 will represent a subset of the set, where 0 represents the empty set (since no elements are present) and 2n-1 is the subset with all elements in it. Incrementing a number from 0 to 2n-1 will enumerate all possible subsets.

The 1 << i corresponds to one of these IDs, b & (1 << i) will check the current subset to see if element i belongs in it.

R: Loop over several column to compare variables

We don't need a loop for this. Just create a logical vector and coerce it to binary (as.integer)

df1$col4 <- as.integer(df1$col2 != df1$col3)

Making a vector on condition in R

You may simply compare the vectors themselves:

df <- data.frame(c1 = col1, c2 = col2)
df$c3 <- as.integer(df$c1 < df$c2)
df

c1 c2 c3
1 1 2 1
2 3 5 1
3 4 1 0
4 5 5 0
5 2 6 1
6 6 5 0
7 7 3 0

Flag each record by comparing two variables in R

df$FlagAB <- ifelse(df$FlagA == 1 & !is.na(df$FlagA) & df$FlagB == 0, 1, 0)
df

ID FlagA FlagB FlagAB
1 28602363 1 0 1
2 28605734 0 1 0
3 28608629 1 0 1
4 28611734 1 0 1
5 28619822 NA 0 0
6 28622689 1 1 0
7 28650295 NA 1 0
8 28650378 0 1 0
9 28651602 1 1 0
10 28656060 1 0 1

EDIT

As noted below, you actually don't need to use ifelse because the result is a logical vector.

as.numeric(df$FlagA == 1 & !is.na(df$FlagA) & df$FlagB == 0)

Element-wise OR operation on vectors in C++

Try using std::transform:
http://www.cplusplus.com/reference/algorithm/transform/

// transform algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::transform
#include <vector> // std::vector
#include <functional> // std::plus

int op_increase (int i) { return ++i; }

int main () {
std::vector<int> foo;
std::vector<int> bar;

// set some values:
for (int i=1; i<6; i++)
foo.push_back (i*10); // foo: 10 20 30 40 50

bar.resize(foo.size()); // allocate space

std::transform (foo.begin(), foo.end(), bar.begin(), op_increase);
// bar: 11 21 31 41 51

// std::plus adds together its two arguments:
std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), std::plus<int>());
// foo: 21 41 61 81 101

std::cout << "foo contains:";
for (std::vector<int>::iterator it=foo.begin(); it!=foo.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';

return 0;
}

Alternative ways to create a repetitive vector in R

We can use bitwAnd

> bitwAnd(0:9, 1)
[1] 0 1 0 1 0 1 0 1 0 1

or kronecker

> kronecker(as.vector(matrix(1, 5)), 0:1)
[1] 0 1 0 1 0 1 0 1 0 1

> kronecker((1:5)^0, 0:1)
[1] 0 1 0 1 0 1 0 1 0 1

or outer

> as.vector(outer(0:1, (1:5)^0))
[1] 0 1 0 1 0 1 0 1 0 1

Elementwise comparison of two vectors while ignoring all NaN's in between

This is how I would do it:

temp1 = vec1(~isnan(vec1));
temp2 = vec2(~isnan(vec2));
m = min(numel(temp1), numel(temp2));
M = max(numel(temp1), numel(temp2));
results = [(temp1(1:m) == temp2(1:m)), false(1,M-m)];

Note that here results is a binary array. If you need it numeric, you can convert it to double for instance.

Regarding your concern about NaNs, depends on what you want to do with your arrays. If you are going to process them, it is more convenient to remove the NaNs. In order to keep the track of things you can keep the index of the kept elements:

id1 = find(~isnan(vec1));
vec1 = vec1(id1);

vec1 =

2 5 8 7 5 3 4

id1 =

3 7 9 12 14 16 18

% and same for vec2

If you decide to remove the NaNs, the solution will be the same, with all temps replaced with vec.

How to get binary output for unique()?

Approach 1

This is memory-intensive, as it creates an intermediate n×n logical matrix, where n is the size of x:

result = sum(triu(bsxfun(@eq, x, x.')))==1;

Since R2016b, this can be expressed more succintly as

result = sum(triu(x==x.'))==1;

How it works

bsxfun(@eq, x, x.') (or x==x.') creates a square matrix of equality comparisons.

triu keeps only the upper triangular part, so that each element is only compared with previous ones or with itself.

sum gives the sum of each column. If the sum is 1 this means that the element is not equal to any previous elements, only to itself.

Approach 2

This is slightly more memory-efficient. It creates an intermediate m×n logical matrix, where m is the number of unique elements and n is the total number of elements:

xu = unique(x);
result = any(diff([false(numel(xu),1) bsxfun(@eq, x, xu.')],[],2)==1);

Since R2016b, the second line can be replaced by

result = any(diff([false(numel(xu),1) x==xu.'],[],2)==1);

How it works

This creates a matrix, say A, of comparisons of each unique element of x (row index of A) with each element of x (column index of A). Let B denote the result of appending a column of false to A.

An element that appears in x for the first time corresponds to a [0 1] subsequence in the corresponding row of B. To detect this, diff is applied along each row, and the result is compared with 1 (which is the increment between the elements in [0 1]).



Related Topics



Leave a reply



Submit