我一直在努力弄清楚如何根据名称为数据框的列设置类。
假设我有一个命名的数据框,我想通过一个函数将一个类添加到一个列。该类在另一个函数中使用列名确定:
library(dplyr)
df1 <- data.frame(hello = 1:4, world = 2:5)
add_class <- function(x, my_class) {
structure(x, class = c(class(x), my_class))
}
get_class_by_column_name <- function(column_name) {
if(grepl("hello", tolower(column_name))) {
return("greeting")
} else {
return("probably_not_greeting")
}
}
这两个东西都按预期工作,分别:
> class(df1$hello)
[1] "integer"
> df1$hello <- add_class(df1$hello, "class_added_manually")
> class(df1$hello)
[1] "integer" "class_added_manually"
> df1$hello <- add_class(df1$hello, get_class_by_column_name("hello"))
> class(df1$hello)
[1] "integer" "class_added_manually" "greeting"
但我想弄清楚如何将它们结合起来。这不起作用:
set_classes_by_column_names <- function(df) {
classes_df <- data.frame(name = names(df), class = '') %>%
rowwise %>%
mutate(class = get_class_by_column_name(name))
print(classes_df)
for (i in 1:length(classes_df$name)) {
add_class(my_column = df[,classes_df$name[i]], # select column by name
my_class = classes_df$class[i]) # use column name as function argument to find class
}
return(df)
}
名称分配仍然有效,但似乎无法添加自定义类。
> df2 <- data.frame(hello = 1:4, world = 2:5)
> class(df2$hello)
[1] "integer"
> df2 <- set_classes_by_column_names(df2)
Source: local data frame [2 x 2]
Groups: <by row>
# A tibble: 2 x 2
name class
<fct> <chr>
1 hello greeting
2 world probably_not_greeting
> class(df2$hello)
[1] "integer"
这里有什么问题?
此外,如果有一种方法可以在 dplyr 管道中执行此操作,而不是 for (i in 1:length(classes_df$name)) {...}
,我会很感兴趣部分。这里的问题是,似乎没有任何函数可用于使用列名称作为参数来改变数据框列,但我的 get_class_by_column_name
需要名称。
最佳答案
可以使用 purrr
包在管道中完成:
library(dplyr)
library(purrr)
set_class_by_name <- function(col, name) {
if (grepl("hello", name)) {
new_class <- "greeting"
} else {
new_class <- "probably_not_greeting"
}
return(structure(col, class = c(class(col), new_class)))
}
df2 <- df1 %>%
imap_dfc(set_class_by_name)
诀窍在 purrr::imap
中,它对列表执行应用类型操作,并且另外将列表的名称作为第二个参数传递。这意味着很容易在自定义函数中获取名称。 _dfc
后缀将输出(列表列表)转换回数据帧。
关于r - 如何根据列名分配数据框列类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55421042/