从可能的标签库中将标签分配给数据框
Assigning labels to a data frame from bank of possible labels
我想创建一个函数来更新来自不同环境的数据框。具体来说,我想使用 Hmisc::label()
函数更新数据框的标签。
assign_label <- function(df, col) {
col <- rlang::as_name(rlang::ensym(col))
Hmisc::label(df[,col]) <- fetch_label(col)
}
fetch_label <- function(col) {
val <- c("mpg" = "MPG",
"hp" = "HP")
unname(val[col])
}
以下代码执行没有问题:assign_label(mtcars, hp)
但是,它实际上并没有改变调用环境中的数据帧。我只是不知道如何让它按照我的想象去做。
理想情况下,我希望能够将数据帧通过管道传递给此函数:
mtcars %>% assign_label(mpg)
关于不在函数范围之外修改的评论,我创建了两个函数,为新数据帧分配标签。
fetch_label <- function(col) {
val <- c("mpg" = "MPG",
"hp" = "HP")
unname(val[col])
}
assign_label <- function(df, col) {
col <- rlang::as_name(rlang::ensym(col))
Hmisc::label(df[[col]]) <- fetch_label(col)
return(df)
}
assign_labels <- function(df) {
purrr::iwalk(df, function(.x, .y) {
lab <- fetch_label(.y)
Hmisc::label(df[[col]]) <<- lab
})
return(df)
}
mtcars <- mtcars %>% assign_label(hp)
mtcars <- mtcars %>% assign_labels()
1) Return modified object 在 R 中不鼓励就地修改对象。通常的方法是 return 数据框和然后将其分配给新名称或恢复为原始名称,破坏或隐藏它。
assign_label <- function(df, col) {
col <- deparse(substitute(col))
Hmisc::label(df[[col]]) <- fetch_label(col)
df
}
mtcars_labelled <- mtcars %>% assign_label(mpg)
2) magrittr 尽管我们上面已经说过,但是在 R 和一些 R 包中有一些修改的工具。 magrittr 包提供了一种用于覆盖或隐藏输入的语法。使用 (1) 中的定义我们可以写成:
library(mtcars)
mtcars %<>% assign_label(mpg)
如果 mtcars 在全局环境中,它会用新值覆盖它,但在这种情况下,mtcars 在数据集中,因此新的 mtcars 被写入调用者并且数据集中的原始值不变。
3) 替换函数 虽然没有广泛使用,R 确实提供了这样定义和使用的替换函数。这确实会覆盖或隐藏输入。
`assign_label<-` <- function(df, value) {
Hmisc::label(df[[value]]) <- fetch_label(value)
df
}
assign_label(mtcars) <- "mpg"
备注
顺便说一句,如果目标是一个与 tidyverse 一致的接口,那么使用 tidyselect 检索列名,以便像下面这样的示例工作:
assign_labels <- function(df, col) {
nms <- names(select(df, {{col}}))
for(nm in nms) Hmisc::label(df[[nm]]) <- fetch_label(nm)
df
}
mtcars_labelled <- mtcars %>% assign_labels(starts_with("mp"))
str(mtcars_labelled)
mtcars_labelled <- mtcars %>% assign_labels(mpg|hp)
str(mtcars_labelled)
我想创建一个函数来更新来自不同环境的数据框。具体来说,我想使用 Hmisc::label()
函数更新数据框的标签。
assign_label <- function(df, col) {
col <- rlang::as_name(rlang::ensym(col))
Hmisc::label(df[,col]) <- fetch_label(col)
}
fetch_label <- function(col) {
val <- c("mpg" = "MPG",
"hp" = "HP")
unname(val[col])
}
以下代码执行没有问题:assign_label(mtcars, hp)
但是,它实际上并没有改变调用环境中的数据帧。我只是不知道如何让它按照我的想象去做。
理想情况下,我希望能够将数据帧通过管道传递给此函数:
mtcars %>% assign_label(mpg)
关于不在函数范围之外修改的评论,我创建了两个函数,为新数据帧分配标签。
fetch_label <- function(col) {
val <- c("mpg" = "MPG",
"hp" = "HP")
unname(val[col])
}
assign_label <- function(df, col) {
col <- rlang::as_name(rlang::ensym(col))
Hmisc::label(df[[col]]) <- fetch_label(col)
return(df)
}
assign_labels <- function(df) {
purrr::iwalk(df, function(.x, .y) {
lab <- fetch_label(.y)
Hmisc::label(df[[col]]) <<- lab
})
return(df)
}
mtcars <- mtcars %>% assign_label(hp)
mtcars <- mtcars %>% assign_labels()
1) Return modified object 在 R 中不鼓励就地修改对象。通常的方法是 return 数据框和然后将其分配给新名称或恢复为原始名称,破坏或隐藏它。
assign_label <- function(df, col) {
col <- deparse(substitute(col))
Hmisc::label(df[[col]]) <- fetch_label(col)
df
}
mtcars_labelled <- mtcars %>% assign_label(mpg)
2) magrittr 尽管我们上面已经说过,但是在 R 和一些 R 包中有一些修改的工具。 magrittr 包提供了一种用于覆盖或隐藏输入的语法。使用 (1) 中的定义我们可以写成:
library(mtcars)
mtcars %<>% assign_label(mpg)
如果 mtcars 在全局环境中,它会用新值覆盖它,但在这种情况下,mtcars 在数据集中,因此新的 mtcars 被写入调用者并且数据集中的原始值不变。
3) 替换函数 虽然没有广泛使用,R 确实提供了这样定义和使用的替换函数。这确实会覆盖或隐藏输入。
`assign_label<-` <- function(df, value) {
Hmisc::label(df[[value]]) <- fetch_label(value)
df
}
assign_label(mtcars) <- "mpg"
备注
顺便说一句,如果目标是一个与 tidyverse 一致的接口,那么使用 tidyselect 检索列名,以便像下面这样的示例工作:
assign_labels <- function(df, col) {
nms <- names(select(df, {{col}}))
for(nm in nms) Hmisc::label(df[[nm]]) <- fetch_label(nm)
df
}
mtcars_labelled <- mtcars %>% assign_labels(starts_with("mp"))
str(mtcars_labelled)
mtcars_labelled <- mtcars %>% assign_labels(mpg|hp)
str(mtcars_labelled)