Frage Zählen der Anzahl von "0" in diesem Faktor


Betrachten Sie den folgenden Faktor

x = factor(c("1|1","1|0","1|1","1|1","0|0","1|1","0|1"))

Ich möchte die Anzahl der Vorkommen des Zeichens "0" in diesem Faktor zählen. Die einzige Lösung, die ich bisher gefunden habe, ist

sum(grepl("0",strsplit(paste(sapply(x, as.character), collapse=""), split="")[[1]]))
# [1] 4

Diese Lösung scheint für solch einen einfachen Prozess sehr kompliziert zu sein. Gibt es eine "bessere" Alternative? (Da der Prozess bei Faktoren, die 2000 Elemente lang sind, etwa 100.000 Mal wiederholt wird, könnte ich mich auch am Ende um die Leistung kümmern.)


5
2018-03-02 01:28


Ursprung


Antworten:


x = factor(c("1|1","1|0","1|1","1|1","0|0","1|1","0|1"))
x
# [1] 1|1 1|0 1|1 1|1 0|0 1|1 0|1
# Levels: 0|0 0|1 1|0 1|1

sum( unlist( lapply( strsplit(as.character(x), "|"), function( x ) length(grep( '0', x ))) ) )
# [1] 4

oder

sum(nchar(gsub("[1 |]", '', x )))
# [1] 4

Basierend auf @Rich Scriven's Kommentar

sum(nchar(gsub("[^0]", '', x )))
# [1] 4

Basierend auf @ thelatemails Kommentar - using tabulate funktioniert viel schneller als die obige Lösung. Hier ist der Vergleich.

sum(nchar(gsub("[^0]", "", levels(x) )) * tabulate(x))

Zeitprofil:

x2 <- sample(x,1e7,replace=TRUE)
system.time(sum(nchar(gsub("[^0]", '', x2 ))));
# user  system elapsed 
# 14.24    0.22   14.65 
system.time(sum(nchar(gsub("[^0]", "", levels(x2) )) * tabulate(x2)));
# user  system elapsed 
# 0.04    0.00    0.04 
system.time(sum(str_count(x2, fixed("0"))))
# user  system elapsed 
# 1.02    0.13    1.25

7
2018-03-02 01:30



Hier sind drei Optionen.

Option 1:  scan() der Vektor mit sep="|"

sum(scan(text=as.character(x), sep="|") == 0)
# [1] 4

Option 2: Ein festes Zeichen in gregexpr()

sum(unlist(gregexpr("0", x, fixed=TRUE)) > 0)
# [1] 4

Option 3: Eine sehr einfache und schnelle Paketoption mit Schnurr

library(stringr)
sum(str_count(x, fixed("0")))
# [1] 4

6
2018-03-02 01:32