我在同一文件夹中有各种不同的CSV文档。所有这些文档都有65列,标题都是相同的两个标题行,它们需要合并到一个文档中。此外,我需要合并标题行。
结构看起来或多或少是这样的:
B2.csv:
TP1 TP1 TP2 TP2 TP2
Value Measurement Condition Time Max_Value
1.09 2.779 1 120 5.885
5.09 2.005 2 180 7.555
9.33 1.889 3 240 1.444
5.00 6.799 4 300 9.125
8.88 3.762 5 360 6.223
B4.csv:
TP1 TP1 TP2 TP2 TP2
Value Measurement Condition Time Max_Value
2.11 4.339 7 120 6.115
5.69 8.025 8 180 7.555
8.38 5.689 9 240 5.244
9.70 7.795 10 300 8.824
8.78 3.769 11 360 3.883
最终文档应如下所示:
TP1_Value TP1_Measurement TP2_Condition TP2_Time TP2_Max_Value
1.09 2.779 1 120 5.885
5.09 2.005 2 180 7.555
9.33 1.889 3 240 1.444
5.00 6.799 4 300 9.125
8.88 3.762 5 360 6.223
2.11 4.339 7 120 6.115
5.69 8.025 8 180 7.555
8.38 5.689 9 240 5.244
9.70 7.795 10 300 8.824
8.78 3.769 11 360 3.883
要合并文档,我使用了以下代码:
setwd("C:/Users/XXXX/Desktop/Data/.")
# Get a List of all files in directory named with a key word, say all `.csv` files
filenames <- list.files("C:/Users/XXXX/Desktop/Data/.", pattern="*.csv", full.names=TRUE)
# Read and row bind all data sets
data <- rbindlist(lapply(filenames,fread))
# Generate new CSV document
write.csv(data, file = "C:/Users/XXXX/Desktop/Data/OneHeader.csv", sep = ",", row.names = FALSE)
但是,使用此代码,第二个标题行保留在数据文件中。要合并这些标题,我将使用以下代码:
# Merging first two lines into one single header
data[] <- lapply(data, as.character)
names(data) <- paste(names(data), data[1, ], sep = "_")
new_data <- data[-1,]
您能帮我吗,如何将代码的这两部分自动合并在一起?
如果有人可以为我提供帮助,我将非常感激,因为我是使用R的初学者。或者还有其他(更好的)方法可以完成此任务吗?
非常感谢您的帮助!
答案 0 :(得分:2)
这里是data.table方法,主要使用fread()
。
由于它按文件读取列名,因此如果游览文件包含不同的标题,它也将起作用。在fill = TRUE
中使用rbindlist()
来填充空白列。
library( data.table )
#get list of files to read
files <- list.files( pattern = "^B[0-9].csv", full.names = TRUE )
#read files to list using lapply
l <- lapply( files, function(x) {
#read the first two rows of each file, and paste them together to get col_names
col_names = transpose( fread( x, nrows = 2 ) )[, .(paste(V1, V2, sep = "_") )][[1]]
#read file from except the first two rows, use col_names as header
dt <- fread( x, skip = 2, col.names = col_names )
})
#bind list together
rbindlist( l, fill = TRUE )
# TP1_Value TP1_Measurement TP2_Condition TP2_Time TP2_Max_Value
# 1: 1.09 2.779 1 120 5.885
# 2: 5.09 2.005 2 180 7.555
# 3: 9.33 1.889 3 240 1.444
# 4: 5.00 6.799 4 300 9.125
# 5: 8.88 3.762 5 360 6.223
# 6: 2.11 4.339 7 120 6.115
# 7: 5.69 8.025 8 180 7.555
# 8: 8.38 5.689 9 240 5.244
# 9: 9.70 7.795 10 300 8.824
# 10: 8.78 3.769 11 360 3.883
然后将结果写入磁盘。
答案 1 :(得分:1)
由于您收集到的标题始终是相同的,因此我只需要使用正则表达式从插入的数据对象中删除这些第二个标题行,如下所示:
data <- data[!grepl(*.Value.*, data$TP1),] # removes all the lines that have the term Value on data$TP1 column
然后,您可以使用以下方法随意重命名第一个标头:
colnames(data) <- c('TP1_Value', ....)
答案 2 :(得分:1)
尝试一下:
filenames <- list.files("C:/Users/XXXX/Desktop/Data/.", pattern="*.csv", full.names=TRUE)
data <- lapply(filenames, read.csv, skip = 2)
dataDF <- as.data.frame(do.call("rbind", data), stringsAsFactors = FALSE)
headersDF<- read.csv(filenames[[1]], nrows= 2, header = FALSE, stringsAsFactors = FALSE)
names(dataDF) <- paste(headersDF[1,], headersDF[2,], sep = "_")
write.csv(data, file = "C:/Users/XXXX/Desktop/Data/OneHeader.csv", sep = ",", row.names = FALSE)
基本上,他会执行以下操作:
第1行使用您提供的目录中的csv文件名创建一个向量。
行2将所有文件中的数据读取到数据帧列表中。它将跳过每个文件的前两行。
第3行将矩阵中的不同数据帧绑定为一个。 (现在您有了文件,缺少的是列名)
第4行将第一个文件(标头)中的前两行读入data.frame。
第5行使用“ _”作为分隔符逐行粘贴两行,并将此字符串设置为列名。
第6行写入您的csv。
答案 3 :(得分:1)
这是基本的R解决方案。
首先,获取文件名。正则表达式模式假定它们都以大写"B"
开头,后跟1个或多个数字,并且文件扩展名为".csv"
。
fnames <- list.files(pattern = "^B\\d+\\.csv")
第二,使用lapply
循环读取它们,跳过第一行。然后,rbind
将几个数据帧放在一起。
df_list <- lapply(fnames, read.table, skip = 2, sep = ",")
df_final <- do.call(rbind, df_list)
现在输入列名。
readLines
读取文本行并将strsplit
分隔为列名的组成部分。
header <- readLines(fnames[1], n = 2)
header <- strsplit(header, ",")
names(df_final) <- paste(header[[1]], header[[2]], sep = "_")
查看结果。
df_final
# TP1_Value TP1_Measurement TP2_Condition TP2_Time TP2_Max_Value
#1 1.09 2.779 1 120 5.885
#2 5.09 2.005 2 180 7.555
#3 9.33 1.889 3 240 1.444
#4 5.00 6.799 4 300 9.125
#5 8.88 3.762 5 360 6.223
#6 2.11 4.339 7 120 6.115
#7 5.69 8.025 8 180 7.555
#8 8.38 5.689 9 240 5.244
#9 9.70 7.795 10 300 8.824
#10 8.78 3.769 11 360 3.883