组合一系列数据框并为每个数据创建新的列
我的Excel数据集中每周都有一个Excel文件。每张纸具有相同的行数,并且每一行在整张纸上都是相同的(除了时间段...纸1代表第1周,第2周第2周等)。我试图导入所有的Excel工作表作为一个数据帧R.组合一系列数据框并为每个数据创建新的列
例如,我的数据本质上是结构化像这样(有几个列和张):
Week 1 sheet
ID Gender DOB Absences Lates Absences_excused
1 M 1997 5 14 5
2 F 1998 4 3 2
Week 2 sheet
ID Gender DOB Absences Lates Absences_excused
1 M 1997 2 10 3
2 F 1998 8 2 9
我试图建立一个脚本,将张X号和它们合并成一个数据帧是这样的:
Combined (ideal)
ID Gender DOB Absences.1 Lates.1 Absences.2 Lates.2
1 M 1997 5 14 2 10
2 F 1998 4 3 8 2
我使用GDATA导入Excel文件。
我试图创建一个循环(通常是坏R,我知道...),将经过所有工作表中的Excel文件,每到一个列表中添加一个数据帧:
library(gdata)
number_sheets <- 3
all.sheets <- vector(mode="list", length=number_sheets)
for (i in 1:number_sheets) {
all.sheets[[i]] <- read.xls("/path/to/file.xlsx", sheet=i)
}
这给我一个很好的清单,all.sheets
,我可以访问,但我不确定从数据框列表中的特定列创建新的数据框的最佳方式。
我试过下面的代码,它通过循环遍历数据框列表来创建一个全新的数据框。在第一个数据框中,它会保存所有工作表中一致的列,然后添加特定于星期的列。
Cleaned <- data.frame()
number_sheets <- 3
for (i in 1:number_sheets) {
if (i == 1) {
Cleaned <- all.sheets[[i]][,c("ID", "Gender", "DOB")]
}
Cleaned$Absences.i <- all.sheets[[i]][,c("Absences")] # wrong... obviously doesn't work... but essentially what I want
# Other week-specific columns go here... somehow...
}
此代码不工作,虽然,因为Cleaned$Absences.i
显然是你,不是如何在数据帧创建动态列。
什么是最好的方式来结合一组数据框,并为我试图跟踪的每个变量创建新列?
额外的障碍:我也试图两列合并,“缺失”和“Absences_excused”到最后的数据帧中的单个“缺席”一栏,所以我试图让我的解决方案,让我执行转换到新的栏目,像这样(再次,这是不对的):
Cleaned$Absences.i <- all.sheets[[i]][,c("Absences")] + all.sheets[[i]][,c("Absences_excused")]
@Dinin我觉得海报的问题比这个例子让我们相信要复杂一点。我认为海报希望进行多合并,如“第1周,第2周第2周等”所示。我的方法有点不同。额外的障碍可以在合并之前使用lapply进行转换。这是我使用3个数据帧而不是2的合并解决方案。
#First read in three data frames
Week_1_sheet <- read.table(text="ID Gender DOB Absences Unexcused_Absences Lates
1 1 M 1997 5 1 14
2 2 F 1998 4 2 3", header=TRUE)
Week_2_sheet <- read.table(text="ID Gender DOB Absences Unexcused_Absences Lates
1 1 M 1997 2 1 10
2 2 F 1998 8 2 2
3 3 M 1998 8 2 2", header=TRUE)
Week_3_sheet <- read.table(text="ID Gender DOB Absences Unexcused_Absences Lates
1 1 M 1997 2 1 10
2 2 F 1998 8 2 2", header=TRUE)
#Put them into a list structure
WEEKlist <- list(Week_1_sheet , Week_2_sheet , Week_3_sheet)
#Transform to add the absences and unexcused absences and drop unexcused
lapply(seq_along(WEEKlist), function(x) {
WEEKlist[[x]] <<- transform(WEEKlist[[x]], Absences=sum(Absences,
Unexcused_Absences))[, -5]
}
)
#Rename each data frame in the list with `<<-` that acts on environments
lapply(seq_along(WEEKlist), function(x) {
y <- names(WEEKlist[[x]])
names(WEEKlist[[x]]) <<- c(y[1:3], paste(y[4:length(y)], ".", x, sep=""))
}
)
#loop through and merge by the common columns
DF <- WEEKlist[[1]][, 1:3]
for (.df in WEEKlist) {
DF <-merge(DF, .df, by=c('ID', 'Gender', 'DOB'), all=TRUE, suffixes=c("", ""))
}
DF
一个第二个方法(重命名数据帧列之后)是使用减少: 从(LINK)
merge.all <- function(frames, by) {
return (Reduce(function(x, y) {merge(x, y, by = by, all = TRUE)}, frames))
}
merge.all(frames=WEEKlist, by=c('ID', 'Gender', 'DOB'))
两者我不知道哪一个是,虽然速度更快。
编辑:在Windows 7计算机上运行1000次迭代的减少是速度快:
test replications elapsed relative user.self sys.self
1 LOOP 1000 10.12 1.62701 7.89 0
2 REDUCE 1000 6.22 1.00000 5.34 0
这是完美的。谢谢! – Andrew 2012-03-04 06:58:49
合并策略是:
> Week_1_sheet <- read.table(text="ID Gender DOB Absences Lates
+ 1 M 1997 5 14
+ 2 F 1998 4 3", header=TRUE)
> Week_2_sheet <- read.table(text="ID Gender DOB Absences Lates
+ 1 M 1997 2 10
+ 2 F 1998 8 2", header=TRUE)
> merge(Week_1_sheet, Week_2_sheet, 1:3)
ID Gender DOB Absences.x Lates.x Absences.y Lates.y
1 1 M 1997 5 14 2 10
2 2 F 1998 4 3 8 2
您可以names(sheet) <- sub("x", 1, sheet)
再次y的重命名列, - > 2.我认为cbi nd策略是可以的,但合并可能更好学习。
@TylerRinker提出了关于'by'参数的可接受参数的问题。帮助页面中的相关参数是:“列可以通过名称,编号或逻辑向量指定:名称”row.names“或编号0指定行名称。”
我不知道你可以在合并中使用列号作为参数。 +1 – 2012-03-04 05:58:27
我想你应该清楚,我们是否可以期待的所有片材具有相同的价值观和顺序名== ID ,性别,生日。如果不是,那么'merge'显然是你想要的功能,如果是这样的话,'cbind'就足够了。 – 2012-03-04 02:21:17
所有工作表都具有相同的值并订购ID,性别,DOB和其他常量列。他们没有相同的缺勤值,缺勤报告等值。 – Andrew 2012-03-04 02:23:53
我没有看到任何“原谅”的列。 – 2012-03-04 02:35:10