加载多个 CSV 文件并为 R 中的列名添加后缀

Load in multiple CSV files and add suffix to column names in R

我正在尝试加载一系列 CSV 文件,然后将后缀附加到 CSV 中的每一列(主键除外 (subject_id)。每个 csv 看起来像这样

subject_id var1 var2
1 55 57
2 55 57

假设此 csv 文件名为 data1,后续文件名为 data2、data3...等

对于我加载的每个 csv,我想将 table 转换成类似

的内容
subject_id var1_data1 var2_data1
1 55 57
2 55 57
subject_id var1_data2 var2_data2
1 55 57
2 55 57

我知道如何加载数据集;

filenames <- list.files(path= "data", full.names = TRUE)

datasets <- lapply(filenames, read_csv) 

但我正在努力弄清楚如何编写 loop/lapply 语句以我想要的方式添加后缀。

下面的函数将添加一个后缀,但它是静态的。

lapply(datasets, function(df) {
  names(df)[-1] <- paste0(names(df)[-1], "_data1")
  df
})

接下来我尝试的是在上面的函数中间插入一个 for 循环

filenames2 <- sub('\.csv$', '', list.files(path = "data"))

lapply(dataset3, function(df) {
  for (val in filenames2){
    names(df)[-1] <- paste0(names(df)[-1], val)
    df
  }
})

但这只会将所有内容更改为 NULL/doesn 不起作用。有没有人想过什么可能是最好的方法?我也对 python 中的解决方案持开放态度,尽管 R 是首选。

谢谢!

如果每个数据集都有相同的列,另一种方法是制作一个 data.frame,其中一列是数据集的来源,这里有一种方法可以做到这一点。

datasets <-
  purrr::map_df(
    .x = filenames,
    .f = read_csv,
    .id = "dataset"
  )

假设我们在最后的注释中生成了可重现的文件。

然后我们得到 fnamesMap 中的文件名,一个函数 Read 读取每个文件并修复返回固定数据帧的名称。

fnames <- Sys.glob("data*.csv")

Read <- function(f) {
  df <- read.csv(f)
  names(df)[-1] <- paste0(names(df[-1]), "_", sub(".csv$", "", basename(f)))
  df
}
L <- Map(Read, fnames)

str(L)

给出这个命名列表:

List of 3
 $ data1.csv:'data.frame':      2 obs. of  3 variables:
  ..$ subject_id: int [1:2] 1 2
  ..$ var1_data1: int [1:2] 55 55
  ..$ var2_data1: int [1:2] 57 57
 $ data2.csv:'data.frame':      2 obs. of  3 variables:
  ..$ subject_id: int [1:2] 1 2
  ..$ var1_data2: int [1:2] 55 55
  ..$ var2_data2: int [1:2] 57 57
 $ data3.csv:'data.frame':      2 obs. of  3 variables:
  ..$ subject_id: int [1:2] 1 2
  ..$ var1_data3: int [1:2] 55 55
  ..$ var2_data3: int [1:2] 57 57

备注

Lines <- "subject_id var1 var2
1 55 57
2 55 57"
data1 <- data2 <- data3 <- read.table(text = Lines, header = TRUE)
for(f in c("data1", "data2", "data3")) write.csv(get(f), paste0(f, ".csv"), row.names = FALSE, quote = FALSE)