Как найти разницу в уровнях между двумя векторами упорядоченных факторов в R?

Допустим, у меня есть два упорядоченных фактора start и end, которые имеют одинаковую длину и используют одни и те же уровни. Как вернуть вектор, показывающий, сколько уровней изменился каждый элемент с start на end?

Так, например, скажем, у нас есть:

start = 'C5',  NA,   'C3',   'C5',   'T1'
end =   'C5', 'C5',   NA  ,  'C6',   'C6'
Levels: C2 < C3 < C4 < C5 < C6 < C7 < C8 < T1 < T2 < T3 < T4 < T5 < T6 < T7 < T8 < T9 < T10 < T11 < T12 < S1 < S2 < S3 < S45

в идеале я хочу, чтобы что-то простое, например end - start, давало мне c(0, NA, NA, 1, -3)

Вот код, устанавливающий приведенный выше пример

lvls<-c("C2","C3","C4","C5","C6","C7","C8",
        "T1","T2","T3","T4","T5","T6","T7","T8","T9","T10","T11","T12",
        "S1","S2","S3","S45")
start<-c('C5',  NA,   'C3',   'C5',   'T1') 
start<-ordered(start,levels=lvls)

end<-c('C5', 'C5',   NA  , 'C6',   'C6')
end<-ordered(end,levels=lvls)

person Frikster    schedule 18.07.2015    source источник


Ответы (1)


Нашел, как мне кажется, излишне сложный способ сделать это. Я с радостью приму более простой и элегантный ответ.

> start_lvls<-sapply(start,function(elem){match(TRUE,c(elem==levels(elem)))})
> end_lvls<-sapply(end,function(elem){match(TRUE,c(elem==levels(elem)))})
> end_lvls-start_lvls
[1]  0 NA NA  1 -3

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

# Returns a vector that is the numeric value of what level each ordered factor in orderedFactorVec is
numericLevels<-function(orderedFactorVec){
  return(sapply(orderedFactorVec,function(elem){match(TRUE,c(elem==levels(elem)))}))
}

# Returns a vector that is the numeric difference between the two given ordered factor vectors (i.e end - start)
levelsChange<-function(start,end){
 return(numericLevels(end)-numericLevels(start)) 
}
person Frikster    schedule 18.07.2015
comment
match векторизован, поэтому match(end, unique(lvls)) - match(start, unique(lvls)). - person Khashaa; 18.07.2015