функция recode (пакет автомобиля) - перекодирует аргумент и знак равенства

Я хотел бы знать, можно ли использовать знак равенства (=) в параметре recodes функции recode в пакете автомобилей?

Например, следующее не работает:

library(car)
n <- c(0, 10, 20, 21, 60, 70)
r <- recode(n, " 0:20 = '<= 20' ; 20:70 = '> 20' ")
# Error in recode(n, " 0:20 = '<= 20' ; 20:70 = '> 20' ") : 
# in recode term:  0:20 = '<= 20' 
# message: Error in parse(text = strsplit(term, "=")[[1]][2]) : 
#  <text>:1:2: unexpected INCOMPLETE_STRING
# 1:  '<
# ^

Удаление = из <= 20 отлично работает:

r <- recode(n, " 0:20 = '< 20' ; 20:70 = '> 20' ")
table(r) 
r
# < 20 > 20 
# 3    3 

Учитывая, что я использую recode в контексте, где я использую аргумент recodes в качестве пользовательского ввода, я надеюсь, что любое решение не требует наличия явных escape-символов, поскольку это было бы обременительно.

Я использую R версии 3.2.3 (2015-12-10) - "Деревянная елка"


person Community    schedule 04.04.2016    source источник
comment
Почему бы просто не заменить его позже? r <- gsub( "~", "=", recode(n, " 0:20 = '<~ 20' ; 20:70 = '> 20' ") )   -  person Ari B. Friedman    schedule 20.04.2016
comment
это очень похоже на ответ @Jianfeng ниже ...   -  person Ben Bolker    schedule 21.04.2016


Ответы (3)


car::recode всегда будет неудобно, поскольку он анализирует строку recode (которая сломается, если где-либо будет стоять «ложный» знак равенства).

Для вашего конкретного приложения cut хорошо работает:

n <- c(0, 10, 20, 21, 60, 70)
cut(n,breaks=c(-1,20,Inf),labels=c("<= 20", ">20"))

plyr::revalue полезен для однозначного сопоставления (см. Также plyr::mapvalues):

x <- factor(c("a","b","c"))
revalue(x,c("a"=">= 20"))

Я не знаю хорошего готового решения "многие к одному":

x <- factor(letters[1:8])
oldvals <- list(c("a","b","c"),c("d","e"),c("f","g","h"))
newvals <- c("new1","new2","new3")
for (i in seq_along(oldvals)) {
    m <- which(levels(x) %in% oldvals[[i]])
    if (length(m)>0) 
       levels(x)[m] <- rep(newvals[i],length(m))
}

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

person Ben Bolker    schedule 20.04.2016

Учитывая, что я использую recode в контексте, где я использую аргумент recodes как вводимые пользователем

Я не уверен, что это значит, но это довольно удобно для конечного пользователя:

map_em = function(
  n, 
  recs = readline(prompt = "enter map like key = value, key2 = value2: \n")
){
    m = eval(parse(text = sprintf("list(%s)", recs)))
    s = stack(m)
    s$ind[ match(n, s$value) ]
}

# usage example
map_em(n)
# enter map like key = value, key2 = value2: 
'<= 20' = 0:20, '> 20' = 21:70
# [1] <= 20 <= 20 <= 20 > 20  > 20  > 20 
# Levels: <= 20 > 20

Поскольку он использует match, ваш пользователь может вводить перекрывающиеся значения (как это сделал OP, записывая 0:20 и 20:70), и он просто возьмет первое совпадение.


Точно так же пользователь может передать отображение непосредственно в вызове функции:

map_em2 = function(n, ...){
    m = list(...)
    s = stack(m)
    s$ind[ match(n, s$value) ]
}

# usage example    
map_em2(n, '<= 20' = 0:20, '> 20' = 21:70)
# [1] <= 20 <= 20 <= 20 > 20  > 20  > 20 
# Levels: <= 20 > 20
person Frank    schedule 20.04.2016

У меня была такая же проблема, и я не нашел решения. Вот мое неуклюжее решение, использующее gsub

r <- recode(n, " 0:20 = '< 20' ; 20:70 = '> 20' ")
r <- gsub("< 20", "<= 20", r)
person Jianfeng    schedule 04.04.2016