wake-up-neo.com

Zählen Sie für jede Spalte eindeutige Werte

Ich möchte die Anzahl der eindeutigen Werte für jede Spalte in einer Tabelle zurückgeben. Wenn ich zum Beispiel die Tabelle habe:

 Testdata <- data.frame(var_1 = c("a","a","a"), var_2 = c("b","b","b"), var_3 = c("c","d","e"))

 var_1 | var_2 | var_3
 a     | b     | c 
 a     | b     | d
 a     | b     | e

Ich möchte die Ausgabe als:

 Variable | Unique_Values
 var_1    | 1
 var_2    | 1
 var_3    | 3

Ich habe versucht, mit Loops mit der einzigartigen Funktion herumzuspielen, z.

 for(i in names(Testdata)){
    # Code using unique function
 }

Ich vermute jedoch, dass es einen einfacheren Weg gibt.

14
Zfunk

Sie könnten apply verwenden:

apply(Testdata, 2, function(x) length(unique(x)))
# var_1 var_2 var_3 
#     1     1     3
25
sgibb

In dplyr:

Testdata %>% summarise_all(funs(n_distinct(.)))
6
leerssej

Dies ist tatsächlich eine Verbesserung gegenüber dem Kommentar von @Ananda Mahto. Es passte nicht in den Kommentar, also entschied ich mich, es als Antwort hinzuzufügen. 

sapply ist etwas schneller als lapply und gibt die Ausgabe in einer kompakteren Form aus, genau wie die Ausgabe von apply.

Ein Testlaufergebnis mit tatsächlichen Daten:

> start <- Sys.time()
> apply(datafile, 2, function(x)length(unique(x)))
          symbol.           date     volume 
             1371            261      53647 
> Sys.time() - start
Time difference of 1.619567 secs
> 
> start <- Sys.time()
> lapply(datafile, function(x)length(unique(x)))
$symbol.
[1] 1371

$date
[1] 261

$volume
[1] 53647

> Sys.time() - start
Time difference of 0.07129478 secs
> 
> start <- Sys.time()
> sapply(datafile, function(x)length(unique(x)))
          symbol.              date             volume 
             1371               261              53647 
> Sys.time() - start
Time difference of 0.06939292 secs

Der datafile hat ungefähr 3,5 Millionen Zeilen.

Zitieren des Hilfetextes:

sapply ist eine benutzerfreundliche Version und standardmäßig ein Wrapper von lapply Rückgabe eines Vektors, einer Matrix oder bei Vereinfachung = "array" eines Arrays if gegebenenfalls durch Anwenden von simplify2array (). sapply (x, f, simplify = FALSE, USE.NAMES = FALSE) ist dasselbe wie lapply (x, f).

5
Tapajit Dey

Verwendung der lengths- Funktion:

lengths(lapply(Testdata, unique))

# var_1 var_2 var_3 
#     1     1     3 
2
zx8754

Hier ist eine Alternative:

aggregate(values ~ ind, unique(stack(Testdata)), length)
#     ind values
# 1 var_1      1
# 2 var_2      1
# 3 var_3      3

Dies erfordert, dass die Spalten character sind.

1
Matthew Plourde

Hier habe ich dplyr und tidyr zum Zählen verwendet (unter Verwendung Ihres Testdata-Datenrahmens):

Testdata %>% 
  gather(var, value) %>% 
  distinct() %>% 
  count(var)

# # A tibble: 3 × 2
#     var     n
#   <chr> <int>
# 1 var_1     1
# 2 var_2     1
# 3 var_3     3
1
Megatron

Ich habe gerade alle Lösungen ausprobiert, und zwei der oben genannten Lösungen funktionierten nicht mit Aggregat und die aufgeräumten, aber zwei von ihnen funktionierten nicht. Ich denke, eine Datentabelle ist eine gute Wahl, 

setDT(Testdata)[, lapply(.SD, uniqueN), .SDcols=c("var_1","var_2","var_3")]
   #    var_1 var_2 var_3
   # 1:     1     1     3

Ich habe versucht, sie miteinander zu vergleichen 

library(microbenchmark)
Mycomp = microbenchmark(
  apply = apply(Testdata, 2, function(x)length(unique(x))),
  lapply = lapply(Testdata, function(x)length(unique(x))),
  sapply = sapply(Testdata, function(x)length(unique(x))),
  #base = aggregate(values ~ ind, unique(stack(Testdata)), length),
  datatable = setDT(Testdata)[, lapply(.SD, uniqueN), .SDcols=c("var_1","var_2","var_3")],
  times=50
)

#Unit: microseconds
#      expr     min      lq     mean   median      uq     max neval cld
#     apply 163.315 176.678 192.0435 181.7915 192.047 608.859    50  b 
#    lapply 138.217 147.339 157.9684 153.0640 165.829 254.145    50 a  
#    sapply 160.338 169.124 178.1486 174.3965 185.548 203.419    50  b 
# datatable 667.937 684.650 698.1306 696.0160 703.390 874.073    50   c
0
user6376316
library(purrr)
Testdata %>% map_dbl(n_distinct)
var_1 var_2 var_3 
    1     1     3 

# in your format
Testdata %>% map_dbl(n_distinct)%>%melt(value.name = "unique_counts")
      unique_counts
var_1             1
var_2             1
var_3             3
0
Vinay