我有200个csv文件,文件名为"a.csv", "b.csv"等
在每个csv文件中,有两列:"type"one_answers";abundance"。我想将每个csv文件中的abundance列的名称更改为"a_abundance";b_abundance"等来匹配文件名,然后用新的列名保存CSV文件。
到目前为止,我有以下内容,但它不起作用:
filenames<- list.files(pattern = ".csv")
all_files <- lapply (filenames, function (x) {
file <- read.csv (x)
name= sub(".*", "", x)
colnames(file) <- paste (colnames(file), name, sep ='_')
return(file)
})
像这样:
all_files <- lapply(setNames(nm=filenames), function(fn) {
dat <- read.csv(fn)
ind <- colnames(dat) == "abundance"
if (any(ind)) {
colnames(dat)[ind] <- paste0(tools::file_path_sans_ext(basename(fn)), "_abundance")
}
dat
})
上面的代码将读取数据并更改一个列名。(你说只有一列,但你的代码正在改变所有列…我将坚持只使用名为"abundance"
的那个
Map(write.csv, all_files, names(all_files))
## or ##
for (nm in names(all_files)) write.csv(all_files[[nm]], nm)
供参考,这可以在命令行(bash shell或类似的,只要sed
可用)上完成快得多,例如:
for fn in $(ls *.csv) ; do
BN=$(basename "$fn" .csv)
sed -i -E "1{s/abundance/${BN}_abundance/}" "$fn"
done
演练:
- 对于
BN
,basename
删除所有开头的目录组件,并且末尾的.csv
从文件名中删除扩展名;这将把./a.csv
转换为a
。 - 对于
sed
:-i
对文件进行就地修改;注意,这不会存储原始文件的备份;如果你使用-i.bak
,那么它会在修改之前备份文件,也许你第一次尝试更安全,然后你可以删除*.bak
文件-E
是一个扩展表达式;你应该也能通过-e
,这只是我的习惯1
表示只在 文件的第一行应用此规则s/from/to/
将文本从from
模式转换为to
模式,在本例中加上${BN}_
(大括号在bash envvar使用中有点防御作用)