Прозрачная таблица поиска для числовых значений без использования data.frame? - PullRequest
0 голосов
/ 04 марта 2019

Advanced R предполагает идею использования подмножества символов для справочных таблиц.

x <- c("m", "f", "u", "f", "f", "m", "m")
lookup <- c(m = "Male", f = "Female", u = NA)
lookup[x]
#>        m        f        u        f        f        m        m 
#>   "Male" "Female"       NA "Female" "Female"   "Male"   "Male"

Создано в 2019-03-04 пакетом Представить (v0.2.1)

Однако эта идея не работает для числовых поисков, поскольку names - это специальный атрибут, который должен быть символом вектором.

Что такое простое эквивалентное решение для числовых поисков, для которого не требуется data.frame?

Я хочу избежать решения data.frame, поскольку сопоставление между ключами и значениями основано только напо порядку, в отличие от более прозрачного 3 = 'Excellent', 2 = 'Good', 1 = 'Poor'.


Решение, использующее data.frame, предлагается в параграфе следующих таблиц поиска символов.

grades <- c(1, 2, 2, 3, 1)

info <- data.frame(
  grade = 3:1,
  desc = c("Excellent", "Good", "Poor"),
  fail = c(F, F, T)
)

info[grades, 'desc']
#> [1] Excellent Good      Good      Poor      Excellent
#> Levels: Excellent Good Poor

Созданона 2019-03-04 пакетом представьте (v0.2.1)

Ответы [ 3 ]

0 голосов
/ 04 марта 2019

Если ваши ключи будут только положительными целыми числами, вы можете использовать значение индекса, предложенное Сореном в ответе на этот вопрос: https://stackoverflow.com/a/54990917


Если нет, вы все равно можете использовать *Стратегия на основе 1005 *, которую вы описали выше, сохраняя свои числа в names(lookup) как символ, а затем используя as.character, чтобы преобразовать вектор числовых ключей в правильную форму для сопоставления:

y <- c(1, -2, 1.3, -5)
lookup_num <- c('1' = 'Cat', '-2' = 'Dog', '1.3' = 'Fish', '-5' = 'Hedgehog')
lookup_num[as.character(y)]
         1         -2        1.3         -5 
     "Cat"      "Dog"     "Fish" "Hedgehog" 

Один из возможных недостатковэтот подход заключается в том, что, поскольку числа будут обрабатываться как строки, они не будут соответствовать 0,0 с 0 или 3,00 с 3, поэтому вам нужно убедиться, что ваши числовые значения чистые.


Если производительность не так важна, вы можете изменить порядок ключей и значений, указав числовой ключ в качестве значения, а значение поиска символов - в качестве имени, а затем использовать sapply для поиска каждого ключа:

lookup_num <- c('Cat' = 1, 'Dog' = -2, 'Fish' = 1.3, 'Hedgehog' = -5)
keys <- c(-2, 1.3, -2, 1)
sapply(keys, function(x) which(lookup_num == x))
 Dog Fish  Dog  Cat 
   2    3    2    1 

Преимущество заключается в использовании сопоставления чисел, которое предотвращает проблемы, вызванные переменным форматированием чисел, и дает вам большую гибкость вtch (например, вы могли бы сделать: abs(lookup_num - x) < 0.1, чтобы добавить место для маневра в вашем числовом соответствии)

Недостатком является то, что он имеет довольно плохую временную сложность, но если ваш список ключей и / или таблица поискане большие, вы не заметите вообще.

0 голосов
/ 05 марта 2019

Вместо этого вы можете использовать функцию поиска.Например, вот простая вспомогательная функция, которая создает для вас функцию поиска:

create.lookup = function(name, value) {
  function(lookup.name) value[match(lookup.name, name)]
}

Пример использования этого:

grades <- c(1, 2, 2, 3, 1)
lookup = create.lookup(c(3, 2, 1), c("Excellent", "Good", "Poor"))
lookup(grades)
# [1] "Poor"      "Good"      "Good"      "Excellent" "Poor"     

Также работает с отрицательными и нецелыми значениями

grades <- c(2, 1.1, 2, -3, 1.1)
lookup = create.lookup(c(1.1, 2, -3), c("Excellent", "Good", "Poor"))
lookup(grades)
# [1] "Good"      "Excellent" "Good"      "Poor"      "Excellent"

И он по-прежнему работает, даже если числа пишутся по-разному

grades <- c(2.000, 1.10, 2, -3e0, 001.1)
lookup(grades)
# [1] "Good"      "Excellent" "Good"      "Poor"      "Excellent"

В качестве дополнительного бонуса, тот же метод также работает для поиска по типу символа, таким образом предоставляя единый метод дляразличные варианты использования

grades <- c('p', 'g', 'g', 'e', 'p')
lookup = create.lookup(c('e', 'g', 'p'), c("Excellent", "Good", "Poor"))
lookup(grades)
# [1] "Poor"      "Good"      "Good"      "Excellent" "Poor"     
0 голосов
/ 04 марта 2019

Вы можете присвоить свое числовое значение индексу в списке и назначить индексу списка место для значения.С вашими числовыми показателями (оценками) вы можете затем искать значения следующим образом:

lookups <- list()
lookups[[1]] <- "Excellent"
lookups[[2]] <- "Good"
lookups[[3]] <- "Fair"
lookups[[4]] <- "Poor"
lookups[[5]] <- "Fail"

grades <- c(1, 2, 2, 3, 1)
lookups[grades]

Это дает категории оценок:

> lookups[grades]
[[1]]
[1] "Excellent"

[[2]]
[1] "Good"

[[3]]
[1] "Good"

[[4]]
[1] "Fair"

[[5]]
[1] "Excellent"

Или далее, чтобы упростить как именованный вектор:

grades <- c(1, 2, 2, 3, 1)
lookups[grades]

setNames(grades,unlist(lookups[grades]))

Выход:

> setNames(grades,unlist(lookups[grades]))
Excellent      Good      Good      Fair Excellent 
        1         2         2         3         1 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...