r - 我可以编写一个函数来重新评估一个因素的水平吗?
问题描述
我的数据框中有一列“lg_with_children”,它有 5 个级别,“一半”、“普通话”、“上海话”、“其他”、“N/A”和“不重要”。我想将 5 个级别压缩到只有 2 个级别,“上海人”和“其他”。
为了做到这一点,我使用了 plyr 包中的 revalue() 函数来成功地重命名关卡。我使用了下面的代码,它运行良好。
data$lg_with_children <- revalue(data$lg_with_children,
c("Mandarin" = "Other"))
data$lg_with_children <- revalue(data$lg_with_children,
c("Half and half" = "Other"))
data$lg_with_children <- revalue(data$lg_with_children,
c("N/A" = "Other"))
data$lg_with_children <- revalue(data$lg_with_children,
c("Not important" = "Other"))
为了稍微压缩代码,我在重新评估关卡并尝试编写函数之前返回了数据。在研究了如何编写自己的函数后,我尝试了以下方法(我对此很陌生)。
revalue_factor_levels <- function(df, col, source, target) {df$col <- revalue(df$col, c("source" = "target"))}
我故意保留了 df、col、source 和 target 泛型,因为我需要以同样的方式重新评估其他一些列。
接下来,我尝试运行填充 args 的代码并收到以下消息:
我不太确定问题是什么。我尝试了以下代码调整,但仍然没有。
revalue_factor_levels <- function(df, col, source, target) {df$col <- revalue(df$col, c(source = target))}
任何指导表示赞赏。谢谢。
解决方案
您可以编写函数来重新编码级别 - 最简单的方法可能是直接更改级别levels(fac) <- list(new_lvl1 = c(old_lvl1, old_lvl2), new_lvl2 = c(old_lvl3, old_lvl4))
但是已经有几个开箱即用的功能。我通常使用forcats
包来操纵因素。
fct_recode
从forcats
包裹中签出。链接到文档。
还有其他功能可以帮助您 - 查看下面的评论。
现在,至于为什么您的代码不起作用:
df$col
查找字面上名为 的列col
。解决方法是改为这样做df[[col]]
。- 不要忘记
df
在函数结束时返回 c(source = target)
将创建一个包含一个名为 的元素的向量"source"
,而不管变量中发生了什么source
。解决方案是分两步创建向量c(source = target)
。
revalue_factor_levels <- function(df, col, source, target) {
to_rename <- target
names(to_rename) <- source
df[[col]] <- revalue(df[[col]], to_rename)
df
}
返回 df 意味着语法是:
data <- revalue_factor_levels(data, "lg_with_children", "Mandarin", "Other")
我喜欢将数据作为第一个参数并返回修改后的数据的函数,因为它们是可管道的。
library(dplyr)
data <- data %>%
revalue_factor_levels("lg_with_children", "Mandarin", "Other") %>%
revalue_factor_levels("lg_with_children", "Half and half", "Other") %>%
revalue_factor_levels("lg_with_children", "N/A", "Other")
尽管如此,使用forcats
起来更容易,并且不太容易在边缘情况下中断。
编辑:
没有什么可以阻止您使用forcats
和创建自定义函数。例如,这更接近您想要实现的目标:
revalue_factor_levels <- function(df, col, ref_level) {
df[[col]] <- forcats::fct_others(df[[col]], keep = ref_level)
df
}
# Will keep Shanghaisese and revalue other levels to "Other".
data <- revalue_factor_levels(data, "lg_with_children", "Shanghainese")
推荐阅读
- ios - 将谷歌地图中的用户坐标存储到 Firebase 数据库中
- vue.js - vue 如何将模型传递给组件并返回选择值?
- express - ApolloServer.applyMiddleware({ express }) 获取 UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'use of undefined
- haskell - 使用堆栈时如何在.cabal中查找依赖项
- sql-server - 使用同一表中另一列的值更新每一行的一部分
- ios - UITableView.visibleCells.contains(JDHeaderTableViewCell()) 总是返回 false
- javascript - 如何修复“鼠标按住可拖动元素”
- jenkins - 如何在下游作业中读取上游作业发送的参数?
- r - 在 R 中创建分类变量
- android - 如何在java中使用ndk获取证书值