2016-07-14 45 views
10

Wyobraź folowing sekwencje:Sortowanie sekwencje binarne R

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

Chcę uporządkować sekwencje w tej kolejności, ze względu na podobieństwo:

0000 
0001 
0010 
0100 
1000 
0011 
... 

Linia 2,3,4,5 mają to samo podobieństwo do linii 1, ponieważ różnią się tylko o jeden bit. Zatem kolejność linii 2,3,4,5 może również wynosić 3,2,5,4.

Linia 6 jest następna, ponieważ różni się o 2 bity od linii1.

Czy można to zrobić za pomocą R?

Odpowiedz

7

Niech

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

1) Korzystanie digitsum funkcji z this odpowiedź:

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) za pomocą wyrażeń regularnych:

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

Zamiast funkcji cyfr, nie możesz tego zrobić: 'x [order (sapply (strsplit (x," "), function (x) sum (x == 1)))] ' – eipi10

+1

@ eipi10, oczywiście, ale prawdopodobnie rozwiązanie regex będzie lepsze niż jakiekolwiek inne, które wymaga sumowania cyfr. – Julius

+0

Zgadzam się. Ale na pewno fajnie jest wymyślić wszystkie drugie najlepsze sposoby robienia rzeczy w R. – eipi10

1

Oto, co próbowałem. Daj mu szansę i zobacz, czy odpowiada Twoim potrzebom. To zależy od pakietu stringr

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

Zadziała tylko wtedy pierwszy wpis to '0000'. OP może potrzebować bardziej ogólnego rozwiązania –

3

Ponieważ mówimy o odległościach smyczkowych możesz użyć funkcji stringdist z pakietu stringdist to zrobić:

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" 

Albo za jednym zamachem:

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