将 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::mapvalues
与dplyr
一起使用?或者更好的是,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)