将 plyr::mapvalues 与 dplyr 一起使用

Posted

技术标签:

【中文标题】将 plyr::mapvalues 与 dplyr 一起使用【英文标题】:Using plyr::mapvalues with dplyr 【发布时间】:2015-03-16 19:27:13 【问题描述】:

plyr::mapvalues可以这样使用:

mapvalues(mtcars$cyl, c(4, 6, 8), c("a", "b", "c"))

但这不起作用:

mtcars %>%
dplyr::select(cyl) %>%
mapvalues(c(4, 6, 8), c("a", "b", "c")) %>%
as.data.frame()

如何将plyr::mapvaluesdplyr 一起使用?或者更好的是,dplyr 等价物是什么?

【问题讨论】:

试试mtcars %>% select(cyl) %>% .$cyl %>% plyr::mapvalues(c(4,6,8), c('a', 'b', 'c'))%>% as.data.frame() mtcars %>% mutate(x = mapvalues(cyl, c(4, 6, 8), c("a", "b", "c"))) %>% select(x) 那行得通。 .$cyl 是做什么的? 你可以同样使用mtcars %>% transmute(cyl = factor(cyl, labels = c("a", "b", "c"))) @luciano 你可以把之前的代码改成mtcars %>% .$cyl %>% plyr::mapvalues(c(4,6,8), c('a', 'b', 'c')) %>% data.frame(cyl=.) 【参考方案1】:

2020 年更新:plyr 现在是一个“退役”包,其官方指南建议改用积极改进和维护的 dplyr 包。所以最好只使用 dplyr,在这种情况下 dplyr::recode() 就像在 other answer 中一样,并且完全避免使用 plyr。

plyr::mapvalues() 与 dplyr 一起使用:

要使用它并返回一列 data.frame:

mtcars %>%
  transmute(cyl = plyr::mapvalues(cyl, c(4, 6, 8), c("a", "b", "c")))

或者,如果您想要单个矢量输出,例如在您的工作示例中,请使用 pull

mtcars %>%
  pull(cyl) %>%
  plyr::mapvalues(., c(4, 6, 8), c("a", "b", "c"))

如果您同时使用 dplyr 和 plyr,请参阅dplyr readme 中的此注释:

如果您同时加载 plyr 和 dplyr 同时。我建议先加载 plyr,然后再加载 dplyr,这样 更快的 dplyr 函数首先出现在搜索路径中。通过和 大,dplyr 和 plyr 提供的任何功能都以类似的方式工作 方式,尽管 dplyr 函数往往更快、更通用。

但请注意,如果已加载 dplyr 而无需加载 plyr,您可以使用 plyr::mapvalues 调用 mapvalues

【讨论】:

【参考方案2】:

问题也提到了

或者更好的是,dplyr 等价物是什么?

等价于重新编码。

http://www.cookbook-r.com/Manipulating_data/Renaming_levels_of_a_factor/

name <- c("John", "Clara", "Smith")
sex <- c(1,2,1)
age <- c(30,32,54)
df <- data.frame(name,sex,age)
df %>% mutate(sex=recode(sex,
`1`="Male",
`2`="Female"))

这会将 1 映射到男性,将 2 映射到女性。

【讨论】:

【参考方案3】:

我是plyr::mapvalues() 的重度用户。我用它来用新值替换字符串中的旧值。比如:

set.seed(1)
data <- data.frame(name = sample(letters[1:5], 100, replace = TRUE))
check_list <- data.frame(old = letters[1:5], new = LETTERS[1:5])

data$name
#> [1] "a" "d" "a" "b" "e" "c" "b" "c" "c" "a" "e" "e" "b" "b"

plyr::mapvalues(data$name, check_list$old, check_list$new)
#> [1] "A" "D" "A" "B" "E" "C" "B" "C" "C" "A" "E" "E" "B" "B" ...

如果我错了,请纠正我,但没有一个同样简洁的dplyr 方法可以做到这一点。你仍然可以使用dplyr::recode() 来做,但是:

dplyr::recode(data$name, !!!setNames(check_list$new, check_list$old))
#> [1] "A" "D" "A" "B" "E" "C" "B" "C" "C" "A" "E" "E" "B" "B" ...

正如the documentation 中所说,命名向量的顺序是 old (name) = new (value),这与 dplyr::mutate()dplyr::rename() 函数相反(编写时,可能稍后已修复)。

将此添加为答案,因为当我忘记并且无法快速找到答案时,我一直在谷歌搜索如何做。也许现在我可以了。解决方案是从函数文档中的最后两行示例修改而来的。

【讨论】:

以上是关于将 plyr::mapvalues 与 dplyr 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

R dplyr,将 mutate 与 na.omit 一起使用会导致错误大小不兼容 (%d)

如何使用 dplyr 将累积列添加到 R 数据框?

R中的条件数据框突变与magrittr和dplyr

加载与安装库的语法。

(更新)R语言 dplyr的group与summarise的使用

如何基于每个数据框中具有不同名称的两列将两个数据框与 dplyr 连接起来? [复制]