将列重命名为文件名-多个csv文件r



我有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"的那个

从这里开始,你可以用重写一个From:
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使用中有点防御作用)