当使用dplyr时,是否有一种替代plyr中的“revalue”函数的方法?

25

我喜欢 plyr 中的 revalue 函数,可以用来替换字符串,它简单易记。

然而,我现在想要迁移到 dplyr,但是它似乎没有 revalue 函数。在 dplyr 中,如何完成之前用 revalue 完成的任务?


你能展示一些可重现的例子吗? - akrun
library(plyr); library(dplyr) - Axeman
3
这里有一个人与我有相同的想法。https://twitter.com/jennybryan/status/524607056696057856 - chinsoon12
5个回答

30

从dplyr_0.5.0版本开始提供了一个名为recode的函数,它与plyr中的revalue非常相似。

以下示例来自recode文档的Examples部分:

set.seed(16)
x = sample(c("a", "b", "c"), 10, replace = TRUE)
x
 [1] "a" "b" "a" "b" "b" "a" "c" "c" "c" "a"

recode(x, a = "Apple", b = "Bear", c = "Car")

   [1] "Car"   "Apple" "Bear"  "Apple" "Car"   "Apple" "Apple" "Car"   "Car"   "Apple"

如果您只定义了要重新编码的一些值,默认情况下,其余部分将填充为NA

recode(x, a = "Apple", c = "Car")
 [1] "Car"   "Apple" NA      "Apple" "Car"   "Apple" "Apple" "Car"   "Car"   "Apple"

使用 .default 参数可以更改此行为。

recode(x, a = "Apple", c = "Car", .default = x)
 [1] "Car"   "Apple" "b"     "Apple" "Car"   "Apple" "Apple" "Car"   "Car"   "Apple"

如果您想用其他值替换缺失的值,可以使用.missing参数。


2
显然这是Hadley支持的答案:请参见https://twitter.com/hadleywickham/status/524614991719067648和https://github.com/hadley/dplyr/issues/631。 - fmark

5
我们可以使用基本的 R 语言中的 chartr 来实现这一点。
chartr("ac", "AC", x)

数据

x <- c("a", "b", "c")

我喜欢你总是发布一个“基本R”解决方案;无论我去哪里,你都在那里@akrun +1。此外,如果有两个长向量,你会如何处理呢?比如在这个例子中。 - Álvaro A. Gutiérrez-Vargas
@ÁlvaroA.Gutiérrez-Vargas 谢谢。我看了你给的链接。它只显示了一个向量。有没有可能链接不正确? - akrun

3

我想评论@aosmith的答案,但我的声誉不够。看来现在的函数的默认设置是不影响未指定的级别。

x = sample(c("a", "b", "c"), 10, replace = TRUE)
x
[1] "c" "c" "b" "b" "a" "b" "c" "c" "c" "b"

recode(x , a = "apple", b = "banana" )

[1] "c"      "c"      "banana" "banana" "apple"  "banana" "c"      "c"      "c"      "banana"

为了将所有未指定的等级更改为NA,应该包括参数.default = NA_character_
recode(x, a = "apple", b = "banana", .default = NA_character_)

[1] "apple"  "banana" "apple"  "banana" "banana" "apple"  NA       NA       NA       "apple" 

0
一个我觉得很方便的替代方法是使用data.tables的mapvalues函数,例如:
df[, variable := mapvalues(variable, old = old_names_string_vector, new = new_names_string_vector)]

0

R 基础解决方案

您可以使用 base 中的 ifelse() 来实现此功能。该函数的参数为 ifelse(test, yes, no)。以下是一个示例:

(x <- sample(c("a", "b", "c"), 5, replace = TRUE))
[1] "c" "a" "b" "a" "a"

ifelse(x == "a", "Apple", x)
[1] "c"     "Apple" "b"     "Apple" "Apple"

如果您想重新编码多个值,可以像这样嵌套使用该函数:
ifelse(x == "a", "Apple", ifelse(x == "b", "Banana", x))
[1] "c"      "Apple"  "Banana" "Apple"  "Apple"

自编函数

如果有很多需要重新编码的值,使用ifelse()函数可能会变得混乱。因此,我这里提供一个自己编写的函数:

my_revalue <- function(x, ...){
  reval <- list(...)

  from <- names(reval)
  to <- unlist(reval)

  out <- eval(parse(text= paste0("{", paste0(paste0("x[x ==", "'", from,"'", "]", "<-", "'", to, "'"), collapse= ";"), ";x", "}")))

  return(out)
}

现在我们可以非常快速地更改多个值:

my_revalue(vec= x, "a" = "Apple", "b" = "Banana", "c" = "Cranberry")
[1] "Cranberry" "Apple"     "Banana"      "Apple"     "Apple"  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接