How to Detect That a Vector Is Subset of Specific Vector

How to detect that a vector is subset of specific vector?

Here's one way

> all(second %in% first)
[1] TRUE

How to check if the exact vector is a subset of another vector of a list

My approach would be (assuming there are no ";" in your string)

# make li unique
li <- unique(li)
# collapse each unique list element to a length-1 string surrounded by ";"
x <- sapply(li, function(x) paste0(";", paste(x, collapse = ";"), ";"))
# check each element, if this is found somewhere in any other element
li[sapply(seq_along(x), function(i) !any(grepl(x[i], x[-i], fixed = TRUE)))]
# [[1]]
# [1] 0 0 NA 0 0 0 0
#
# [[2]]
# [1] 0 0 0 NA NA 0

However, it seems that OP should make up a larger example and clarify some of the questions brought up in comments to other answers.

Note: in this answer I define x as a subset of y if and only if the exact sequence of x is present in y without any other elements inbetween. That's how I understood the question.

How to check whether a vector is subset of another one in R?

You can test if length is == and if any values of A have a 1 on positions where B has a 1 and combine the conditions with &&.

length(A) == length(B) && any(A[B==1]==1)
#[1] TRUE

Fulfilling the condition in the original question: A and B have the same length and thus have the same number of elements; yet, A is a subset of B, since A has elements 1 in the same place as B.

To fulfill:

  • A and B have the same length and thus have the same number of elements;
  • A should have at least one 1 at places wherever B has 1
  • A can have only 0s at all places where B has 0s.
length(A) == length(B) && any(A[B==1]==1) && all(A[B==0]==0)

To fulfill:

  • A and B have the same length and thus have the same number of elements;
  • A can have only 0s at all places where B has 0s.
length(A) == length(B) && all(A[B==0]==0)

How to check whether a vector is a subset of another in c++

Copy the vectors. Sort the copies. Then use std::includes on the copies.

template <typename T>
bool IsSubset(std::vector<T> A, std::vector<T> B)
{
std::sort(A.begin(), A.end());
std::sort(B.begin(), B.end());
return std::includes(A.begin(), A.end(), B.begin(), B.end());
}

How do I check if one vector is a subset of another?

Try this:

if (std::includes(set_one.begin(), set_one.end(),
set_two.begin(), set_two.end()))
{
// ...
}

About includes().

The includes() algorithm compares two
sorted sequences and returns true if
every element in the range [start2,
finish2) is contained in the range
[start1, finish1). It returns false
otherwise. includes() assumes that the
sequences are sorted using
operator<(), or using the predicate
comp.

runs in

At most ((finish1 - start1) + (finish2
- start2)) * 2 - 1 comparisons are performed.

Plus O(nlog(n)) for sorting vectors. You won't get it any faster than that.

R function to check if a vector is a subset of another

We may paste the vector into string and use grepl to check if the substring is found or not

grepl(paste(values_saved_dice, collapse = ""), paste(x, collapse = ""))
[1] FALSE

How to detect all possible subsets from a given vector?

One way to think about the power set of a given (ordered) set is to think of its elements (the subsets) as bit vectors where the n-th bit is set to 1 if and only if the n-th element from the set was chosen for this subset.

So in your example, you'd have a 3 bit vector that could be represented as an unsigned integer. You'd “count the bit vector” up from 0 (the empty set) to 7 (the entire set). Then, in each iteration, you pick those elements for which the respective bit is set.

As can be readily seen, the power set explodes rapidly which will make it impractical to compute explicitly for any set with more than a dozen or so elements.

Casting these thoughts into C++, we get the following.

#include <climits>      // CHAR_BIT
#include <iostream> // std::cout, std::endl
#include <stdexcept> // std::invalid_argument
#include <type_traits> // std::is_arithmetic
#include <vector> // std::vector

template<typename T>
std::vector<T>
get_subset_sums(const std::vector<T>& elements)
{
static_assert(std::is_arithmetic<T>::value, "T must be arithmetic");
if (elements.size() > CHAR_BIT * sizeof(unsigned long))
throw std::invalid_argument {"too many elements"};
const std::size_t power_size {1UL << elements.size()};
std::vector<T> subset_sums {};
subset_sums.reserve(power_size);
for (unsigned long mask = 0UL; mask < power_size; ++mask)
{
T sum {};
for (std::size_t i = 0; i < elements.size(); ++i)
{
if (mask & (1UL << i))
sum += elements.at(i);
}
subset_sums.push_back(sum);
}
return subset_sums;
}

int
main()
{
std::vector<int> elements {1, 2, 3};
for (const int sum : get_subset_sums(elements))
std::cout << sum << std::endl;
return 0;
}

You might want to use a std::unordered_set for the subset-sums instead of a std::vector to save the space (and redundant further processing) for duplicates.

The program outputs the numbers 0 (the empty sum), 1 (= 1), 2 (= 2), 3 (= 1 + 2), 3 (= 3), 4 (= 1 + 3), 5 (= 2 + 3) and 6 (= 1 + 2 + 3). We can make this more visual.

 mask        mask
(decimal) (binary) subset sum
–––––––––––––––––––––––––––––––––––––––––––––––––
0 000 {} 0
1 001 {1} 1
2 010 {2} 2
3 011 {1, 2} 3
4 100 {3} 3
5 101 {1, 3} 4
6 110 {2, 3} 5
7 111 {1, 2, 3} 6

How can I determine whether a vector contains another vector respecting order in R?

You can collapse your vector into a regex pattern and use grepl

vec1 <- c("a", "b", "c")
vec2 <- c("a", "b", "c", "d", "e")
grepl(paste(vec1, collapse=".*"), paste(vec2, collapse=""))
# TRUE
vec3 <- c("e", "d", "c", "b", "a")
grepl(paste(vec1, collapse=".*"), paste(vec3, collapse=""))
# FALSE
vec4 <- c("a", "x", "b", "c", "y")
grepl(paste(vec1, collapse=".*"), paste(vec4, collapse=""))
# TRUE

EDIT: Based on G5W's comment, you can add a delimiter in case each element is not a character but might be a short string. The delimiter will break up the entries of your vector

vec5 <- c("a", "b", "c")
vec6 <- c("ab", "c")
vec7 <- c("ab", "e", "c", "d")
grepl(paste(vec5, collapse="-.*"), paste(vec7, collapse="-"))
# FALSE
grepl(paste(vec6, collapse="-.*"), paste(vec7, collapse="-"))
# TRUE

Subset a vector and retrieve first elements if exceed the length in R

I think I got it!

v <- c("A", "B", "C", "D")
p <- sample(1:length(v), 1)
r <- c(v[p:length(v)])
c(r, v[!(v %in% r)])[1:3]

And the outputs:

v <- c("A", "B", "C", "D") # your vector

r <- c(v[2:length(v)])
c(r, v[!(v %in% r)])[1:3]
#> [1] "B" "C" "D"

r <- c(v[3:length(v)])
c(r, v[!(v %in% r)])[1:3]
#> [1] "C" "D" "A"

r <- c(v[4:length(v)])
c(r, v[!(v %in% r)])[1:3]
#> [1] "D" "A" "B"

Created on 2022-05-16 by the reprex package (v2.0.1)

Wrapped in a function:

f <- function(v, nth) {
r <- c(v[nth:length(v)])
return(c(r, v[!(v %in% r)])[1:3])
}


Related Topics



Leave a reply



Submit