2016-04-04 4 views
4

Я хотел бы знать, разрешено ли использовать равные (=) параметр recodes функции recode в пакете автомобилей?recode (car package) функция - пересчитывает аргумент и знак равенства

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

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) - «Деревянные елочные»

+1

Почему бы не просто заменить его позже? 'r <- gsub (" ~ "," = ", recode (n," 0:20 = '<~ 20'; 20:70 = '> 20' "))' –

+0

, что довольно похоже на ответ @ Jianfeng ниже ... –

ответ

1

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

r <- recode(n, " 0:20 = '< 20' ; 20:70 = '> 20' ") 
r <- gsub("< 20", "<= 20", r) 
2

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)) 
} 

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

2

Учитывая, я использую 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, ваш пользователь может ввести overlappin g (например, 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