我正在寻找一些方法来改变一个数据框中的变量类,方法是使用另一个数据框的引用,该数据框具有每个变量的类信息。
我有一个包含大约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中做到这一点?
谢谢!
普拉萨德
答案 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)