Reputation: 597
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
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
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
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
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
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()
Upvotes: 13
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