【问题标题】:How to loop twice over files' names in R如何在R中循环两次文件名
【发布时间】:2018-07-29 12:49:02
【问题描述】:

假设我正在对两个主题(实际上是 20 个)进行研究。由于每个主题生成 27 个文件,我需要将这些文件组合起来生成额外的 9 个文件,我想自动化这个过程!

我有一个在九个级别上变化的因素: AA、AB、AM、BA、BB、BM、MA、MB、MM。

对于每个处理我得到三个输出文件,例如对于我得到的 AA 处理: AA1.csv、AA1.txt 和 AA1log.txt。

我需要在这些文件上运行一个脚本(我们称之为 R1);它将它们组合在一个摘要文件中。然后我需要在我生成的所有摘要文件上运行另一个脚本(我称之为 R2)。

所有主题的所有输出文件都在一个文件夹“数据”中。

(对于 R 示例,感谢@ManuelBickel)

# make sure you are in a safe directory!

### Generate the toy data ###

# I define the main directories I need
dir_project = "test"
dirs = list(
  dir_project = dir_project
  ,dir_data = paste0(dir_project, "/data")
  ,dir_summary = paste0(dir_project, "/summary")
  ,dir_plots= paste0(dir_project, "/plots")
)
# create dirs
lapply(dirs, dir.create)

# create some exemplary data and write it in dir
m = matrix(1:4, nrow = 2)
data = list(AA = m, AB = m, AM = m
            ,BA = m, BB = m, BM = m,
            MA = m, MB = m, MM =m)

# generate the csv files for subject 1 and 2
for (i in 1:length(data)) {
  write.csv(data[[i]], file = paste0(dirs[["dir_data"]], "/", names(data[i]), "1.csv"))  
}

for (i in 1:length(data)) {
write.csv(data[[i]], file = paste0(dirs[["dir_data"]], "/", names(data[i]), "2.csv"))  
}

# Generate the .txt files for subjects 1 and 2
for (i in
1:length(data)) {
  write.table(data[[i]], file = paste0(dirs[["dir_data"]], "/", names(data[i]), "1.txt"))  
}

for (i in 1:length(data)) {
  write.table(data[[i]], file = paste0(dirs[["dir_data"]], "/", names(data[i]), "2.txt"))  
}

 # Generate the log.txt files for subjects 1 and 2
for (i in 1:length(data)) {
  write.table(data[[i]], file = paste0(dirs[["dir_data"]], "/", names(data[i]), "1log.txt"))  
}

for (i in 1:length(data)) {
  write.table(data[[i]], file = paste0(dirs[["dir_data"]], "/", names(data[i]), "2log.txt"))  
}

以下是我的数据文件夹中的文件:

list.files(dirs[["dir_data"]])

# [1] "AA1.csv"    "AA1.txt"    "AA1log.txt" "AA2.csv"    "AA2.txt"    "AA2log.txt" "AB1.csv"    "AB1.txt"    "AB1log.txt"
# [10] "AB2.csv"    "AB2.txt"    "AB2log.txt" "AM1.csv"    "AM1.txt"    "AM1log.txt" "AM2.csv"    "AM2.txt"    "AM2log.txt"
# [19] "BA1.csv"    "BA1.txt"    "BA1log.txt" "BA2.csv"    "BA2.txt"    "BA2log.txt" "BB1.csv"    "BB1.txt"    "BB1log.txt"
# [28] "BB2.csv"    "BB2.txt"    "BB2log.txt" "BM1.csv"    "BM1.txt"    "BM1log.txt" "BM2.csv"    "BM2.txt"    "BM2log.txt"
# [37] "MA1.csv"    "MA1.txt"    "MA1log.txt" "MA2.csv"    "MA2.txt"    "MA2log.txt" "MB1.csv"    "MB1.txt"    "MB1log.txt"
# [46] "MB2.csv"    "MB2.txt"    "MB2log.txt" "MM1.csv"    "MM1.txt"    "MM1log.txt" "MM2.csv"    "MM2.txt"    "MM2log.txt"

现在我需要我的代码来选择文件:AA1.csv、AA1.txt 和 AA1log.txt 并在它们上运行脚本 R1。

脚本 R1 将生成一个 csv 文件作为输出,该文件将作为“summaryAA1_csv”放入文件夹“data”中。它还将生成 32 个 png。文件(AA1_1.png、AA1_2.png 等)将进入文件夹“plots”中的子文件夹“AA1”。

然后我将从文件夹“data”中挑选出主题 1 的所有摘要文件并运行脚本 R2。

首先,我需要选择主题 1 生成的所有数据集;然后我需要选择由相同处理产生的那些(首先是所有 AA,然后是 AB 等)。完成九次治疗后,我将转到主题 2。

假设这就是 R1 正在做的事情:

temp = read.csv("test/data/AA1.csv", sep=",", row.names=1)
temp1 <- as.matrix(temp) 
temp2 <- read.table("test/data/AA1.txt")
temp3 <- read.table("test/data/AA1log.txt")
summaryAA1 <- temp1 + temp2 + temp3
summaryAA1

在我编写 R1 代码时,还会生成位于不同文件夹中的图(每种处理 32 个!)

dir.create("test/plots/AA1plots")
png(filename="test/plots//AA1plots/AA1_1_plot.png")
plot(summaryAA1)
dev.off()

我的问题是如何让我的代码选择两次文件;首先选择引用相同治疗(AA)和相同主题编号的文件;运行完所有治疗后,转到为第二个受试者引用相同治疗的文件。

我也愿意接受有关更方便的命名系统的建议,这可能会使循环更方便。

【问题讨论】:

  • 您可以这样做,x &lt;- expand.grid(c("A","B","M"),c("A","B","M")) orders &lt;- do.call("paste0",x[order(x$Var1,x$Var2),]),然后使用命令每次迭代每个对象。例如:“AA”对象只有两个结果,1 和 2,这似乎是一致的,因此您可以迭代这些对象两次。我不能完全回答这个问题,因为你的问题缺乏一个可重复的例子(这也是可以理解的),虽然它很清楚,但我不确定这里的最终目标是什么。谢谢

标签: r for-loop


【解决方案1】:

考虑组织您的输入(受试者和治疗组合列表)和过程(R1 和 R2)。然后适当地调用它们:

subjects <- c(1, 2)
treatments <- c("AA", "AB", "AM", "BA", "BB", "BM", "MA", "MB", "MM")

r1_list <- as.vector(sapply(subjects, function(x,y) paste0(y,x), treatments))
# [1] "AA1" "AB1" "AM1" "BA1" "BB1" "BM1" "MA1" "MB1" "MM1" "AA2" "AB2" "AM2" "BA2" "BB2" "BM2" "MA2" "MB2" "MM2"

r2_list <- sapply(subjects, function(x,y) paste0(y,x), treatments, simplify = FALSE)
r2_list
# [[1]]
# [1] "AA1" "AB1" "AM1" "BA1" "BB1" "BM1" "MA1" "MB1" "MM1"

# [[2]]
# [1] "AA2" "AB2" "AM2" "BA2" "BB2" "BM2" "MA2" "MB2" "MM2"

R1 脚本

setwd("test")

my_func1 <- function(f){
    temp = read.csv(paste0("data/", f, ".csv"), row.names=1)
    temp1 <- as.matrix(temp) 
    temp2 <- read.table(paste0("data/", f, ".txt"))
    temp3 <- read.table(paste0("data/", f, "log.txt"))

    # SUMMARIES
    summary_all <- temp1 + temp2 + temp3
    summary_data <- read.csv(paste0("summary", f, ".csv"))

    ...

    # IMAGES
    for (i in seq(1,32)) {
        dir.create(paste0("plots/", f, "plots"))
        png(filename=paste0("plots/", f, "plots/", f, "_", i, "_plot.png"))
        plot(...)
        dev.off()
    }
}

# CREATE ALL SUMMARY AND IMAGE FILES
for (j in r1_list) my_func1(j)

R2 脚本

my_func2 <- function(items){
    files <- paste0("summary", items, ".csv")

    # READ ALL SUMMARY FILES INTO A LIST OF DATA FRAMES
    df_list <- lapply(files, read.csv)

    # PROCESS LIST
    ...    
}

# PROCESS SUMMARY FILES
for (j in r2_list) my_func2(j)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多