R:一次将多个集合转换为数据帧

时间:2019-05-07 15:34:09

标签: r

我有31个数据集,与31位教师的数据相对应。我需要对所有这些数据集执行多个转换。其中之一就是将它们全部转换成数据帧

 class(alexandre)
[1] "tbl_df"     "tbl"        "data.frame"

正如我所说,我有31个相似的数据集,我需要将所有数据集都转换为数据帧。我这样做的代码是

alexandre <- as.data.frame(alexandre)
adrian <- as.data.frame(adrian)
akemi <- as.data.frame(akemi)
arcanjo <- as.data.frame(arcanjo)
ana_barbara <- as.data.frame(ana_barbara)
brigida <- as.data.frame(brigida)
cleiton <- as.data.frame(cleiton)
daniela <- as.data.frame(daniela)
davi <- as.data.frame(davi)
eliezer <- as.data.frame(eliezer)
eduardo <- as.data.frame(eduardo)
eustaquio <- as.data.frame(eustaquio)
gilberto <- as.data.frame(gilberto)
gilmar <- as.data.frame(gilmar)
jorge <- as.data.frame(jorge)
juarez <- as.data.frame(juarez)
junior <- as.data.frame(junior)

...并在此代码中添加一些行(此行31行)。显然,所有这些代码行都占用了太多空间,并且必须有一种更快(更优雅)的方式来完成此任务。实际上,我尝试过

teachers <- c(alexandre, akemi, adrian, brigida, davi, ...)

cnames <- function(x){
  colnames(x) <- c(1:18)
}

mapply(cnames, teachers)

然后,我将用几行代码来完成所有工作。这种方法(形成一个包含所有数据集的向量,然后在向量上使用mapply)将使我的工作更加轻松,因为正如我所说,我必须对所有这些数据集执行多次转换。

但是,此代码不起作用。我收到以下错误:

 Error in `colnames<-`(`*tmp*`, value = c(1:18)) : 
  attempt to set 'colnames' on an object with less than two dimensions

我发现此错误消息非常不启发。我不知道该怎么做才能使代码正常工作,这显然就是为什么我在这里。欢迎使用其他任何方法来完成我要尝试的操作。谢谢。

2 个答案:

答案 0 :(得分:3)

正如SO的R标签中所评论和经常讨论的那样,只需使用一个列表即可维护所有单独的,结构相似的数据帧。这样做可以为您带来以下好处:

  1. 使用循环轻松地在所有项目上一致地运行操作,或者应用家族调用而无需单独的命名分配。

  2. 通过维护一个对象(通过数字或名称轻松引用)来组织您的环境和工作区,而不是在整个全球环境中泛滥的31个对象。

  3. 通过rbindcbindsplitby或其他操作促进数据帧的迁移和处理。


要在全局环境中创建所有当前数据帧的列表,请对数据帧对象使用eapplymget过滤。每个返回一个命名的数据帧列表。

teachers_df_list <- Filter(is.data.frame, eapply(.GlobalEnv, identity))

teachers_df_list <- Filter(is.data.frame, mget(x=ls()))

或者,使用list.files之类的列表对象从文件源中最初获取数据帧:

teachers_df_list <- lapply(list.files(...), function(f) read.csv(f, ...))

如果存储在列表中,则不会丢失数据框的功能。

head(teachers_df_list$alexandre)
tail(teachers_df_list$adrian)
summary(teachers_df_list$akemi)
...

然后使用lapply运行所需的操作,例如使用右侧功能setNames重命名列。运行其他所需的操作:aggregatelm

new_teachers_df_list <- lapply(teachers_df_list, 
                               function(df) setNames(df, paste0("col_", c(1:18)))

new_teachers_agg_list <- lapply(teachers_df_list, 
                                function(df) aggregate(col1 ~ col2, df, sum))

new_teachers_model_list <- lapply(teachers_df_list, 
                                  function(df) summary(lm(col1 ~ col2, df)))

甚至可以使用do.call + rbind将所有数据帧编译为一个主版本:

# ADD A TEACHER INDICATOR COLUMN
new_teachers_df_list <- Map(function(df, n) transform(df, teacher=n),
                            new_teachers_df_list, names(new_teachers_df_list))

# BUILD SINGLE DF
teachers_df <- do.call(rbind, new_teachers_df_list)

如果以后需要,甚至可以将split主版本重新划分为单独的分组:

# SPLIT BACK TO LIST OF DFs
teachers_df_list <- split(teachers_df, teachers_df$teacher)

答案 1 :(得分:1)

也许您可以使用列表来存储所有data.frame。似乎可行,但是之后您需要找到一种方法来提取列表中的所有data.frame。

df_1 <- data.frame(c(0, 1, 0), c(3, 4, 5))
df_2 <- data.frame(c(0, 1, 0), c(3, 4, 5))

l <- list(df_1, df_2)

lapply(l, function(x){
  colnames(x) <- 1:2
  return(x)
})