2016-07-14 20 views
10

die Folowing Sequenzen Stellen Sie sich vor:Sortierung binäre Sequenzen mit R

0000 
0001 
0010 
0011 
0100 
0101 
0110 
0111 
1000 
1001 
1010 
1011 
1100 
1101 
1110 
1111 

Ich mag die Sequenzen in dieser Reihenfolge sortieren, wegen der Ähnlichkeit:

0000 
0001 
0010 
0100 
1000 
0011 
... 

Linie 2,3,4,5 haben die gleiche Ähnlichkeit wie Zeile 1, da sie sich nur um ein Bit unterscheiden. Die Reihenfolge der Zeilen 2,3,4,5 kann also 3,2,5,4 sein.

Zeile 6 kommt als nächstes, weil sie um 2 Bits von Zeile1 abweicht.

Könnte dies mit R gemacht werden?

Antwort

7

Lassen

x <- c("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", 
     "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111") 

1) Mit digitsum Funktion von this Antwort:

digitsum <- function(x) sum(floor(x/10^(0:(nchar(x) - 1))) %% 10) 
x[order(sapply(as.numeric(x), digitsum))] 
# [1] "0000" "0001" "0010" "0100" "1000" "0011" "0101" "0110" "1001" "1010" "1100" 
# [12] "0111" "1011" "1101" "1110" "1111" 

2) Verwenden von regulären Ausdrücken:

x[order(gsub(0, "", x))] 
# [1] "0000" "0001" "0010" "0100" "1000" "0011" "0101" "0110" "1001" "1010" "1100" 
# [12] "0111" "1011" "1101" "1110" "1111" 
+0

Anstelle der Digitalsumme-Funktion konnte man das nicht tun: 'x [Ordnung (sapply (strsplit (x," "), Funktion (x) Summe (x == 1)))] ' – eipi10

+1

@ eipi10, sicher, aber wahrscheinlich wird die Regex-Lösung besser sein als jede andere, die Digit-Summierung beinhaltet. – Julius

+0

Ich stimme zu. Aber es macht Spaß, die zweit besten Wege zu finden, Sachen in R. zu machen. – eipi10

1

Nun, hier ist, was ich ausprobiert habe. Probieren Sie es aus und sehen Sie, ob es Ihren Bedürfnissen entspricht. Es hängt von dem stringr Paket

library('stringr') 
# Creates a small test data frame to mimic the data you have. 
df <- data.frame(numbers = c('0000', '0001', '0010', '0011', '0100', '0101', '0111', '1000'), stringsAsFactors = FALSE) 
df$count <- str_count(df$numbers, '1') # Counts instances of 1 occurring in each string 
df[with(df, order(count)), ] # Orders data frame by number of counts. 

    numbers count 
1 0000  0 
2 0001  1 
3 0010  1 
5 0100  1 
8 1000  1 
4 0011  2 
6 0101  2 
7 0111  3 
+0

Dies funktioniert nur, wenn der erste Eintrag ist '0000'. OP könnte eine allgemeinere Lösung wünschen –

3

Da wir über String Entfernungen sprechen Sie vielleicht die stringdist Funktion aus dem stringdist Paket verwenden möchten, dies zu tun:

library(stringdist) 
x <- c("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", 
     "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111") 

#stringdistmatrix(x) will calculate the pairwise distances from the lowest value 
#0000 in this case 
distances <- stringdistmatrix(x, '0000') 

#use the distances to order the vector 
x[order(distances)] 
#[1] "0000" "0001" "0010" "0100" "1000" "0011" "0101" "0110" 
# "1001" "1010" "1100" "0111" "1011" "1101" "1110" "1111" 

Oder in einem Rutsch:

x[order(stringdist(x, '0000'))]