Die schnellste und einfachste Lösung mit Rcpp
:
#include <Rcpp.h>
using namespace Rcpp;
inline bool same(SEXP a, SEXP b) {
return R_compute_identical(a, b, 0);
}
// [[Rcpp::export]]
bool identical_impl(List x) {
std::size_t n = x.size();
for (std::size_t i = 1; i < n; ++i)
if (!same(x[0], x[i])) return false;
return true;
}
/*** R
identical2 <- function(...) {
identical_impl(list(...))
}
*/
einige Benchmarks mit anderen Lösungen:
A <- 1:10
B <- 1:10
C <- 1:10
D <- 1:10
E <- 1:12
identical2 <- function(...) {
identical_impl(list(...))
}
identical3 <- function(...) {
length(unique(list(...))) == 1L
}
identical4 <- function(...) {
l <- list(...)
all(vapply(l[-1], l[[1]], FUN = identical,
FUN.VALUE = logical(1L), USE.NAMES = FALSE))
}
identical5 <- function(...) {
l <- list(...)
Vectorize(identical, 'x')(l[-1], l[[1L]])
}
identical6 <- function(...) {
l <- list(...)
for (i in seq_along(l)) {
if (!identical(l[[1]], l[[i]])) return(FALSE)
}
return(TRUE)
}
identical7 <- function(...) {
l <- list(...)
for (i in seq_along(l)) {
for (j in seq_along(l)) {
if (i >= j) next
if (!identical(l[[1]], l[[i]])) return(FALSE)
}
}
return(TRUE)
}
library(microbenchmark)
microbenchmark(
identical2(A, B, C, D, E),
identical3(A, B, C, D, E),
identical4(A, B, C, D, E),
identical5(A, B, C, D, E),
identical6(A, B, C, D, E),
identical7(A, B, C, D, E))
Ergebnisse:
Unit: microseconds
expr min lq mean median uq max neval cld
identical2(A, B, C, D, E) 3.401 4.3065 5.32136 5.1245 5.5420 21.529 100 a
identical3(A, B, C, D, E) 6.480 7.8675 9.20970 8.3875 9.0175 26.739 100 b
identical4(A, B, C, D, E) 12.233 13.5680 15.48014 14.7755 15.5455 48.333 100 c
identical5(A, B, C, D, E) 90.177 93.1480 98.79570 95.2685 103.2765 178.657 100 e
identical6(A, B, C, D, E) 10.683 12.0650 13.43184 12.6820 13.4060 22.314 100 c
identical7(A, B, C, D, E) 28.202 31.0800 34.97819 32.4630 39.4960 68.902 100 d
Eine leichte Verbesserung wäre die Verwendung der all() - Funktion vor sapply(), so dass sie eine einzelne wahr/falsch zurückgibt. – Andy