首页 > 解决方案 > 如何动态更改数据框中列的数据类型

问题描述

我从中将数据导入 R 的平台不支持指定数据类型,因此我的所有列都是character. 我有一个 Excel 文件,它指定哪些列是factor,包括相关的labelslevels。现在,我正在尝试编写一个函数来动态更改我的 data.frame 各列的数据类型

感谢对这个问题的出色回答(dplyr - mutate: use dynamic variable names),我设法编写了以下函数,其中我动态地将列名设置为mutate函数。

readFactorData <- function(filepath) {
    t <- read.xlsx(filepath)
    sapply(nrow(t), function(i) {
      colname <- as.character(t[i, "Item"])
      factorLevels <- t[i, 3:ncol(t)][which(!is.na(t[i, 3:ncol(t)]))]
      totalLevels <- length(factorLevels)
      listOfLabels <- as.character(unlist(factorLevels))

      mutate(d, !!colname := factor(d[[colname]], labels=(1:totalLevels), levels=listOfLabels))
        # requires dplyr v.0.7+
        # the syntax `!!variablename:=` forces evaluation of the variablename before evaluating the rest of the function
    })
}

它有效,每次迭代都会返回整个数据框,相关列 ( colname) 更改为因子。但是,每次迭代都会覆盖前一次,所以这个函数只返回最后一个结果i。如何确保我最终得到 1 个单个数据框,其中保存了所有相关列?

示例数据(确保注释掉上面函数的第一行,因为我们在t这里定义):

 d <- data.frame("id" = sample(100:999, 10), "age" = sample(18:80, 10), "factor1" = c(rep("a", 3), rep("b", 3), rep("c", 4)), "factor2" = c("x","y","y","y","y","x","x","x","x","y"), stringsAsFactors = FALSE)
 t <- data.frame("Item" = c("factor1","factor2"), "Label" = c("This is factor 1", "This is factor 2"), "level1" = c("a","x"), "level2" = c("b","y"), "level3" = c("c","NA"))

标签: rdplyrsapply

解决方案


如果您想将所有您的内容转换factorcharacter您的内容,data.frame您可以使用dplyr's mutate_if。否则,如果您想使用列名向量,@Eden Z 的答案将为您完成。

library(tidyverse)

d_out <- d %>% 
  mutate_if(is.character, as.factor)

d_out

#    id age factor1 factor2
#1  933  61       a       x
#2  208  52       a       y
#3  193  25       a       y
#4  231  47       b       y
#5  595  78       b       y
#6  675  28       b       x
#7  387  71       c       x
#8  386  80       c       x
#9  893  20       c       x
#10 272  23       c       y

当您可以检查变量的类时:

sapply(d_out, class)

#       id       age   factor1   factor2 
#"integer" "integer"  "factor"  "factor" 

推荐阅读