2016-07-14 3 views
10

Представьте себе на следующие последовательности:Сортировка двоичных последовательностей с R

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

Я хочу, чтобы отсортировать последовательности в таком порядке, из-за сходство:

0000 
0001 
0010 
0100 
1000 
0011 
... 

линия 2,3,4,5 имеют одинаковое сходство с строкой 1, потому что они отличаются только одним битом. Таким образом, порядок строк 2,3,4,5 также может составлять 3,2,5,4.

Линия 6 приходит далее, потому что она отличается на 2 бита от строки1.

Это можно сделать с помощью R?

ответ

7

Пусть

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

1) Использование digitsum функции от this ответа:

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) Использование регулярных выражений:

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

Вместо функции digitsum вы не могли бы этого сделать: 'x [order (sapply (strsplit (x," "), function (x) sum (x == 1)))] ' – eipi10

+1

@ eipi10, конечно, но, вероятно, решение регулярных выражений будет более аккуратным, чем любое другое, что связано с суммированием цифр. – Julius

+0

Согласен. Но это, конечно, забавно выяснить все лучшие способы сделать что-то в R. – eipi10

1

Ну, вот что я пробовал. Сделайте снимок и посмотрите, подходит ли оно вашим потребностям. Это зависит от 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

Это работает только в первой записи это '0000'. OP может хотеть более общее решение –

3

Поскольку мы говорим о строковых расстояниях вы можете использовать функцию stringdist из stringdist пакета, чтобы сделать это:

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" 

Или на одном дыхании:

x[order(stringdist(x, '0000'))] 
Смежные вопросы