使用另一个参考数据框更改数据框中的变量类

时间:2016-10-28 11:49:37

标签: r class dataframe reference data.table

我正在寻找一些方法来改变一个数据框中的变量类,方法是使用另一个数据框的引用,该数据框具有每个变量的类信息。

我有一个包含大约150个变量的数据。所有变量都是字符格式。现在我想根据类型改变每个变量的类。为此,我们创建了一个单独的数据框,其中包含每个变量的类信息。让我用一个示例数据框来解释。

将我的原始数据框视为具有5个变量的df -

df <- data.frame(A="a",B="1",C="111111",D="d",E="e")

现在我们有另一个数据框&#34; variable_info&#34;它只包含2个变量,一个&#34; variable_name&#34;和另一个&#34; variable_class&#34;。

variable_info <- data.frame(variable_name=c("A","B","C","D","E"),variable_class=c("character","integer","numeric","character","character"))

现在使用variable_info数据框我想更改df中每个变量的类,以便它们的类在&#34; variable_info $ variable_class&#34;中指定。将变量名称与&#34; variable_info $ variable_name&#34;

相关联

我们如何为数据框执行此操作?在data.table中执行此操作会很好吗?我们怎么能在data.table中做到这一点?

谢谢!

普拉萨德

3 个答案:

答案 0 :(得分:3)

你可以这样试试:

确保两个表的顺序相同:

variable_info <- variable_info[match(variable_info$variable_name, names(df)),]

创建函数调用列表:

funs <- sapply(paste0("as.", variable_info$variable_class), match.fun)

然后将它们映射到每一列:

df[] <- Map(function(dd, f) f(as.character(dd)), df, funs)

使用data.table,您可以采用几乎相同的方式执行此操作,除非您将最后一行替换为:

library(data.table)
dt <- as.data.table(df) # or use setDT(df)
dt[, names(dt) := Map(function(dd, f) f(as.character(dd)), dt, funs)]

答案 1 :(得分:0)

另一种方法是使用一种功能。这个函数可以接受任何一对数据帧,找到它们的公共列,并将第一个类分配给第二个列中的列。

    matchColClasses<- function(df1, df2){
    # Purpose:  protect joins from column type mismatches - a problem with multi-column empty df          
    # Input:    df1 - master for class assignments, df2 - for col reclass and return.
    # Output:   df2 with shared columns classed to match df1
    # Usage:    df2 <- matchColClasses(df1, df2)

      sharedColNames <- names(df1)[names(df1) %in% names(df2)]
      sharedColTypes <- sapply(df1[,sharedColNames], class)

      for (n in sharedColNames) {
        class(df2[, n]) <- sharedColTypes[n]
      }

      return(df2)
     }

答案 2 :(得分:0)

这是@talats答案的改编,我使用purrr中的map2进行了更新,我认为它比Map更简洁,更易于阅读和键入,并且还使用了data.table中的.SD语法。

这也可能使代码的哪些部分是任意函数名而哪些不是呢?

library(purrr)
library(data.table)

dtx <- data.table(A="a",B="1",C="111111",D="d",E="e")
variable_info <- data.table(variable_name=c("A","B","C","D","E"),variable_class=c("character","integer","numeric","character","character"))

map_chr(dtx, typeof)

# make sure they are in the same order
variable_info <- variable_info[match(variable_info$variable_name, names(dtx)),]

# functions to apply
funs <- sapply(paste0("as.", variable_info$variable_class), match.fun)

# apply'em
dtx[, names(dtx) := map2(.SD, funs, ~ .y(as.character(.x)), )]

map_chr(dtx, typeof)