r - 如何根据列名分配数据框列类?

标签 r dplyr

我一直在努力弄清楚如何根据名称为数据框的列设置类。

假设我有一个命名的数据框,我想通过一个函数将一个类添加到一个列。该类在另一个函数中使用列名确定:

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/

相关文章:

r - 选择具有最小绝对差异的重复行观察

r - ggplot 用于多个分类变量——计数数据

r - 将一个向量作为子向量放入另一个向量 R

r - For 跨多个 ggplot 图表的循环

r - 有没有办法对不同长度的变量进行 wilcoxon 检验?

r - 如何将 dplyr::tbl 连接编码更改为 utf8?

r - 在 dplyr 的函数中使用变量名

html - 如何编写 Shiny 的侧边栏折叠以仅显示图标

r - 将 Tibble 转换为 R 中的向量列表

将长数据框 reshape 为宽数据框并使用一列作为前缀重命名新列