Обдумывая это, единственная функция, которую "уровень" должен реализовать, чтобы иметь действительный фактор, - это средство доступа [
. Таким образом, любой объект, реализующий метод доступа [
, можно рассматривать как вектор с точки зрения любой сопрягающей функции.
Я посмотрел в класс hash , но увидел, что он использует нормальное поведение R (как видно из списков), возвращая фрагмент исходного хэша, когда используется только одна скобка (при извлечении фактическое значение при использовании двойной скобки). Однако, если бы я переопределил это с помощью setMethod (), я действительно смог получить желаемое поведение.
library(hash)
setMethod(
'[' ,
signature( x="hash", i="ANY", j="missing", drop = "missing") ,
function(
x,i,j, ... ,
drop
) {
if (class(i) == "factor"){
#presumably trying to lookup the values associated with the ordered keys in this hash
toReturn <- NULL
for (k in make.keys(as.integer(i))){
toReturn <- c(toReturn, get(k, envir=x@.xData))
}
return(toReturn)
}
#default, just make keys and get from the environment
toReturn <- NULL
for (k in make.keys(i)){
toReturn <- c(toReturn, get(k, envir=x@.xData))
}
return(toReturn)
}
)
as.character.hash <- function(h){
as.character(values(h))
}
print.hash <- function(h){
print(as.character(h))
}
h <- hash(1:26, letters)
df <- data.frame(ID=1:26, letter=26:1, stringsAsFactors=FALSE)
attributes(df$letter)$class <- "factor"
attributes(df$letter)$levels <- h
> df
ID letter
1 1 z
2 2 y
3 3 x
4 4 w
5 5 v
6 6 u
7 7 t
8 8 s
9 9 r
10 10 q
11 11 p
12 12 o
13 13 n
14 14 m
15 15 l
16 16 k
17 17 j
18 18 i
19 19 h
20 20 g
21 21 f
22 22 e
23 23 d
24 24 c
25 25 b
26 26 a
> attributes(df$letter)$levels
<hash> containing 26 key-value pair(s).
1 : a
10 : j
11 : k
12 : l
13 : m
14 : n
15 : o
16 : p
17 : q
18 : r
19 : s
2 : b
20 : t
21 : u
22 : v
23 : w
24 : x
25 : y
26 : z
3 : c
4 : d
5 : e
6 : f
7 : g
8 : h
9 : i
>
> df[1,2]
[1] z
Levels: a j k l m n o p q r s b t u v w x y z c d e f g h i
> as.integer(df$letter)
[1] 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2
[26] 1
Есть отзывы по этому поводу? Как я могу сказать, все работает. Похоже, что он работает должным образом, что касается печати, и базовые данные, хранящиеся в фактическом data.frame, не тронуты, поэтому я не чувствую, что я что-то там подвергаю опасности. Возможно, мне даже удастся добавить новый класс в мой пакет, который просто реализует этот метод доступа, чтобы избежать необходимости добавлять зависимость от хеш-класса.
Буду очень признателен за любые отзывы или замечания по поводу того, что я пропускаю.