Carlo
Carlo

Reputation: 597

How to know if a vector is composed by the same elements?

How can I check if a vector has all the same elements?

For example let's say I have:

vec1 = rep(10,20)
vec2 = seq(1:20)

How can I show that vec1 has all the same elements?

Upvotes: 12

Views: 984

Answers (7)

Andrew
Andrew

Reputation: 5138

Another quick/efficient option for numeric vectors is to use max() == min(). I.e., if the max value is equal to the minimum value (na.rm = FALSE by default), all elements are equal:

vec1 = rep(10,20)
vec2 = seq(1:20)

max(vec1) == min(vec1)
[1] TRUE
max(vec2) == min(vec2)
[1] FALSE

EDIT: note, if there are possibly NA's this will need adaption to treat it as-needed. Also, side-note, the memory allocation is very low on my machine (I tested on vectors up to 1e8 and it remained at zero).

Upvotes: 1

tmfmnk
tmfmnk

Reputation: 39858

You can also calculate the standard deviation and assess whether it is zero:

sd(vec1) == 0

[1] TRUE

Or using table():

length(table(vec1)) == 1

Or using rle():

length(rle(vec1)$lengths) == 1

Upvotes: 2

lonelyLearner
lonelyLearner

Reputation: 41

You can convert it into a factor and get the levels which should be only 1 value if they are all same.

vec1 <- (10,20)

vec <- factor(vec1)

levels(vec)

Upvotes: 1

Rui Barradas
Rui Barradas

Reputation: 76402

An option is diff.

diff(vec1)

If the elements are equal, their difference is zero.

all(diff(vec1) == 0)
#[1] TRUE

Or compare the vector to its first element.

all(vec1 == vec1[1])
#[1] TRUE

Edit.

Several ways of determining if all elements of a vector are equal were posted, see RHertel, Yuriy Saraykin, tmfmnk. Here are comparative tests.

library(microbenchmark)
library(ggplot2)

f <- function(n){
  x <- rep(10, n)
  mb <- microbenchmark(
    var = var(x) == 0,
    sd = sd(x) == 0,
    diff = all(diff(x) == 0),
    extract = all(x == x[1]),
    unique = length(unique(x)) == 1
  )
  mb
}

sizes <- c(10, 100, seq(1e3, 1e4, by = 1e3))
mb_list <- lapply(sizes, f)
names(mb_list) <- sizes

res <- lapply(seq_along(mb_list), function(i){
  agg <- aggregate(time ~ expr, mb_list[[i]], median)
  agg$size <- sizes[i]
  agg
})
res <- do.call(rbind, res)

ggplot(res, aes(size, time, colour = expr)) +
  geom_point() +
  geom_line()

enter image description here

Upvotes: 13

akrun
akrun

Reputation: 887048

We can use n_distinct from dplyr

library(dplyr)
n_distinct(vec1)

Upvotes: 2

Yuriy Saraykin
Yuriy Saraykin

Reputation: 8880

count the number of unique values

length(unique(vec1))

Upvotes: 4

RHertel
RHertel

Reputation: 23788

Use the variance. If all elements of a vector are equal, the variance is zero:

allElementsEqual <- function(x) {!var(x)}

#allElementsEqual(vec1)
#[1] TRUE
#allElementsEqual(vec2)
#[1] FALSE

Upvotes: 8

Related Questions