4

我想知道是否允许在 car 包中的函数参数中使用等号( =) ?recodesrecode

例如,以下失败:

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:  '<
# ^

删除=from<= 20工作正常:

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

鉴于我recode在将参数作为用户输入的上下文中使用recodes,我希望任何解决方案都不需要显式转义字符,因为这会很麻烦。

我正在运行 R 版本 3.2.3 (2015-12-10)——“木制圣诞树”

4

3 回答 3

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

如果新/旧代码以某种病态方式重叠,这可能会有点难看......

于 2016-04-20T19:58:24.867 回答
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,您的用户可以输入重叠值(就像 OP 所做的那样,写入0:2020: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
于 2016-04-20T21:27:32.703 回答
1

我有同样的问题,没有找到任何解决方案。这是我笨拙的解决方案,使用gsub

r <- recode(n, " 0:20 = '< 20' ; 20:70 = '> 20' ")
r <- gsub("< 20", "<= 20", r)
于 2016-04-04T22:20:56.067 回答