我有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
我发现此错误消息非常不启发。我不知道该怎么做才能使代码正常工作,这显然就是为什么我在这里。欢迎使用其他任何方法来完成我要尝试的操作。谢谢。
答案 0 :(得分:3)
正如SO的R标签中所评论和经常讨论的那样,只需使用一个列表即可维护所有单独的,结构相似的数据帧。这样做可以为您带来以下好处:
使用循环轻松地在所有项目上一致地运行操作,或者应用家族调用而无需单独的命名分配。
通过维护一个对象(通过数字或名称轻松引用)来组织您的环境和工作区,而不是在整个全球环境中泛滥的31个对象。
通过rbind
,cbind
,split
,by
或其他操作促进数据帧的迁移和处理。
要在全局环境中创建所有当前数据帧的列表,请对数据帧对象使用eapply
或mget
过滤。每个返回一个命名的数据帧列表。
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
重命名列。运行其他所需的操作:aggregate
或lm
。
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)
})