Подтвердить что ты не робот

Сортировка двоичных последовательностей с 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?

4b9b3361

Ответ 1

Пусть

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

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

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"

Ответ 2

Поскольку мы говорим о строковых расстояниях, вы можете использовать функцию 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'))]

Ответ 3

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