【问题标题】:Append files based on their names根据文件名附加文件
【发布时间】:2019-10-05 16:56:12
【问题描述】:

我是 R 新手,我在同一文件夹中有很多文本格式的气候数据文件,名称很长,例如“tasmax_SAM-44_ICHEC-EC-EARTH_rcp26_r12i1p1_SMHI-RCA4_v3_day_20060101-20101231.txt”,其中每个术语分开“_”对应于变量、域、机构、场景等特征。 我想要的是一个代码,它允许我选择文件夹中与模型名称、场景名称、gcm 名称同名的所有文件并按行附加它们。

我尝试的是首先创建文件列表并为其名称的每个部分分配变量,例如 model_name、gcm_name 等。 然后创建了一个条件,我通过循环比较文件中的这些变量。

file <- list.files ( pattern = '*.txt' ) 

group <- function(input){

index = which(file == input)

df=read.table(input,header=FALSE,sep="")

fname= unlist((strsplit(input,"_")),use.names=FALSE)

model_name=fname[3]

sce_name=fname[4]

gcm_name=fname[6]

m=1

for (m in 1:length(file)) {

  if (model_name[m]==model_name[m+1] & sce_name[m]==sce_name[m+1] & gcm_name[m]==gcm_name[m+1]) {

    data=rbind(df[m],df[m+1])

  } else  {}

}
  }

for (i in 1:length(file)) {
  group(file[i])
}

我的代码的错误是这样的:

if (model_name[m] == model_name[m + 1] & sce_name[m] == 中的错误 sce_name[m + : 需要 TRUE/FALSE 的缺失值

最后,代码应该附加满足 if 条件的文件,例如从这两个文件中创建一个文件:

  1. tasmax_SAM-44_ICHEC-EC-EARTH_rcp26_r12i1p1_SMHI-RCA4_v3_day_20060101-20101231.txt

  2. tasmax_SAM-44_ICHEC-EC-EARTH_rcp26_r12i1p1_SMHI-RCA4_v3_day_20110101-20151231.txt

非常欢迎任何帮助和建议!

【问题讨论】:

  • 您的 if 条件有误。 [m+1] 的值不存在。这里有一个问题:你只想将文件与第一个读取文件名称的文件结合起来吗?
  • 感谢您的帮助,但我没有看到另一种遍历索引的方法,有什么建议吗?
  • 是的,我想选择所有同名的文件,从 2006 年到 2100 年。我提交了两个文件名来显示我想如何对它们进行分组。

标签: r file append


【解决方案1】:

我会建议一种完全不同的方法:

获取所有txt文件的列表:

file <- list.files ( pattern = '*.txt' )

将所有文件读入一个数据框:

library(dplyr)
library(readr)
df <- suppressMessages(do.call(bind_rows,lapply(file, read_csv, col_names = FALSE)))

然后group_by你想要的字段并将每一帧写入一个单独的csv文件

df %>%
    group_by(X3, X4, X6) %>%
    do(write_csv(., paste(.$X3, .$X4, .$X6, ".csv", sep = "_")))

【讨论】:

  • 感谢您的帮助,但我不明白如何使用您建议的代码连接 X3、X4 和 X6,您能解释一下吗?因为在每个文本文件中我只有日期和变量。因此,如果我将所有系列放在一起,我无法区分不同的型号名称和场景。谢谢
【解决方案2】:

不确定我是否完全了解您的问题,但这可能会有所帮助:

代码如下

  1. 读取您作为输入提供的文件的值。
  2. 遍历所有其他文件并在它们符合您的条件时附加它们。

If 条件检查您输入的值,然后将其与文件[m] 的名称进行比较。如果为真,它会附加到您的数据中。另一个解决方法:您必须在函数末尾使用return(data)

file &lt;- list.files ( pattern = '*.txt' )

group <- function(input){

  index = which(file == input)

  data=read.table(input,header=FALSE,sep="")

  fname= unlist((strsplit(input,"_")),use.names=FALSE)

  model_name=fname[3]

  sce_name=fname[4]

  gcm_name=fname[6]

  for (m in 2:length(file)) {

    index = file[m]

    df_new=read.table(file[m],header=FALSE,sep="")

    fname= unlist((strsplit(input,"_")),use.names=FALSE)

    if (model_name==fname[3] & sce_name==fname[4] & gcm_name==fname[6]) {

      data=rbind(data,df_new)

    } else  {}

  }
  return(data)
}

group(file[1])

还有待解决的问题:如果不输入第一个文件,则必须解决。由于此代码使用您在group 函数中输入的文件。但是 for 循环与第二个文件一起使用。所以如果你使用group(file[3]),第一个文件将被跳过,第三个文件将加倍。你可以使用类似另一个 if 条件的东西。 if(file==input){skip}(不是实际语法,只是为了一个想法,还要确保你的循环范围是正确的)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-29
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2015-10-09
    • 2018-02-21
    • 2019-02-27
    相关资源
    最近更新 更多