Как зациклить несколько файлов, выполнить некоторые операции и записать все переменные из цикла в файл? - PullRequest
0 голосов
/ 19 января 2019

Я новичок в R, так что простите, это просто.

Я читаю в какой-то таблице:

library(data.table)
require(magrittr); require(tidyr)

x=fread("merged_plot_SG", header=TRUE)

> head(x)
          gene_id chr  min_POS  max_POS      rs_id pvalue_G pvalue_E     metaP
1 ENSG00000020922  11 94212567 95223359 rs11605546   0.1367   0.9353 0.2670442
2 ENSG00000020922  11 94212567 95223359   rs566917   0.2740   0.2275 0.9363864
3 ENSG00000020922  11 94212567 95223359 rs12286498   0.8961   0.3347 0.5552598
4 ENSG00000020922  11 94212567 95223359  rs7934178   0.9043   0.3353 0.5510581
5 ENSG00000020922  11 94212567 95223359 rs16924610   0.9047   0.3353 0.5507136
6 ENSG00000020922  11 94212567 95223359  rs2508783   0.8685   0.1382 0.3517432
...

в этой таблице я хочу извлечь все уникальные (x $ chr), в этом случае:

    > unique(x$chr)
[1] 11  3  6  7 20 17  2 12  1 10  4 19  9 22

, чем для каждого из этих уникальных чисел, которые я хочу загрузить файл, как, например, первое здесь это 11, поэтому я бы сделал:

b=fread("/mydir/bed_chr_11.bed")

и следующие:

b=fread("/mydir/bed_chr_3.bed")
b=fread("/mydir/bed_chr_6.bed")
...

далее я бы сделал эти две операции:

 x00=x %>%
  inner_join(b, by = c("rs_id" = "V4")) %>%
  select(gene_id, chr, rs_id, pvalue_G, pvalue_E, V2, V3)


x11=x00 %<>%
  unite(snp, chr, V3, remove = FALSE)

итак, у меня будут все эти фреймы данных:

x11,x3,x6,x7,x20,x17,x2,x12,x1,x10,x4,x19,x9,x22

тогда я бы соединил их всех в одном фрейме данных и записал в файл:

x.n <- c('x11','x3','x6','x7','x20','x17','x2','x12','x1','x10','x4','x19','x9','x22')
x.list <- lapply(x.n, get)
xx=do.call(rbind, x.list)

colnames(xx)[6] <- "pvalue"
write.table(xx, "ready_plot_SG", quote=F, col.names=TRUE,row.names = F)

Не могли бы вы помочь, как сделать все это в одном скрипте и с помощью цикла?

Спасибо!

РЕДАКТИРОВАТЬ: следующий совет ниже я пришел к этой точке:

require(dplyr)
library(data.table)
require(magrittr); require(tidyr)

x=fread("merged_plot_RGL", header=TRUE)
num=unique(x$chr)

files=list.files(path = "/anika/bed/", pattern = "\\.bed$", full.names = FALSE)

data_dir <- "/anika/bed"

#loop over the initial files
for(i in num){
  file <- paste0(data_dir,"/", "bed_chr_",num[i],".bed")  # loaded .bed file


    xx <- lapply(file, function(z){
    b <- fread(z, header = TRUE)
    data.table(
        x %>%
          inner_join(b, by = c("rs_id" = "V4")) %>%
          select(gene_id, chr, rs_id, pvalue_G, pvalue_E, V2, V3) %>%
          unite(snp, chr, V3, remove = FALSE)
       )

})
  #We can combine them using data.tables 'rbindlist'
  x_final <- rbindlist(xx)
  #now we can use data.tables 'fwrite' to output the table to a file
  names(x_final)[6] <- "pvalue"
  fwrite(x_final, "test_rgl.txt", quote = "F", col.names = TRUE, row.names = FALSE)
}

Но я получил эту ошибку:

    Error: `by` can't contain join column `V4` which is missing from RHS
Execution halted

1 Ответ

0 голосов
/ 19 января 2019

Из описания вашего вопроса я постараюсь дать ответ в меру своих возможностей. Кажется, у нас есть несколько файлов на каждом шаге. Я предлагаю использовать внешний цикл for с функцией внутреннего применения, которую вы можете использовать для чтения и выполнения желаемых преобразований.

initial_dir <- "directory to the folder with the initial data"
data_dir <- "directory to the folder containing the secondary data"

file_names <- c("lots of file names") #1: Insert any number of files here from which to read numbers for the bed_chr_[nr].bed files here
#loop over the initial files
for(i in file_names){
  file <- paste0(initial_dir,"/", i)
  x <- fread(file, header = TRUE)
  #combine secondary path and name 
  secondary_files <- paste0(data_dir,"/bed_chr_", unique(x[, [Insert the column for which the value for the bed_chr_[nr].bed files are in the intitial variable here <--]), ".bed")  #2: insert column name (note i added unique)
  #Apply the desired transformation
  xx <- lapply(secondary_files, function(z){ #lapply will apply the 'function' to each element in 'secondary_files'.
      b <- fread(z) 
      data.table( #apply the transformation and return a table to the list
        x %>% 
          inner_join(b, by = c("rs_id" = "V4")) %>%
          select(gene_id, chr, rs_id, pvalue_G, pvalue_E, V2, V3) %>%
          unite(snp, chr, V3, remove = FALSE)
       )
    }) #after the lapply has run xx contains all the tables from the bed_chr_[numbers].bed files. All will have been read.
  #xx is now a list that contains all the table after applying 
  #We can combine them using data.tables 'rbindlist'
  x_final <- rbindlist(xx)
  #now we can use data.tables 'fwrite' to output the table to a file
  names(x_final)[6] <- "pvalue"
  fwrite(x_final, "ready_plot_sg.txt", quote = "F", col.names = TRUE, row.names = FALSE) #here all the bed_chr_[numbers].bed files will be output into a single combined file
}

Примечания: Я использовал paste0 вместо пасты. Они оба объединяют строки в R, разница в том, что paste0 имеет стандартный аргумент sep = "", где paste вставляет пробел по умолчанию lapply применит функцию к списку, вектору или подобному и выведет результат в виде списка. Можно также использовать vapply или sapply, но это не обязательно даст вам список результатов, что в данном случае желательно для использования rbindlist без каких-либо дополнительных параметров. В целях моего примера я предположил, что в вашем преобразовании b не было ошибок.

::: Редактировать ::: Из нового фрагмента, добавленного опрашивающим, я в специальном случае перепишу опубликованный мною код, чтобы показать, как они должны были быть объединены:

require(dplyr);library(data.table);require(magrittr); require(tidyr)
initial_dir <- "" #The base directory in 'edit' was none ("merged_plot_RGL" is in working directory)
data_dir <- "anika/bed"

file_names <- c("merged_plot_RGL") #1: I inserted the merged_plot_RGL, as this contains the labels for the 'bed' files.
#Note: This loop is now redundant as we only have 1 file. But for illustration it was kept (i will only take on 'merged_plot_RGL' as a value)
for(i in file_names){
  file <- i #2: Sets current file to merged_plot_RGL. paste0 removed as intial_dir was empty ("")
  x <- fread(file, header = TRUE)  #3: loads in merged_plot_RGL as a data.table
  #4: combine secondary path and name (Note: I extract the number from x's chr column)
  secondary_files <- paste0(data_dir,"/bed_chr_", unique(x[, chr]), ".bed")  
  #5: Apply the desired transformation via lapply (Note: xx becomes a list of transformed data from the bed files)
  xx <- lapply(secondary_files, function(z){ 
      b <- fread(z) #5.1: First read in the .bed file (done 1 by 1)
      data.table( #5.2: apply the transformation and return a table to the list
        x %>% 
          inner_join(b, by = c("rs_id" = "V4")) %>% #Note: Questioneers error came
          select(gene_id, chr, rs_id, pvalue_G, pvalue_E, V2, V3) %>%
          unite(snp, chr, V3, remove = FALSE)
       )
    }) 
  #Note: After the lapply has run, and read in each .bed file, xx is now a list of .bed data tables that have been transformed by inner join, select and unite.
  #6: We can combine them using data.tables 'rbindlist'
  x_final <- rbindlist(xx)
  #7: now we can use data.tables 'fwrite' to output the table to a file
  names(x_final)[6] <- "pvalue"
  fwrite(x_final, "ready_plot_sg.txt", quote = "F", col.names = TRUE, row.names = FALSE) 
}

::: Редактировать 2 ::: более короткая версия с более легким чтением ошибок.

require(dplyr);library(data.table);require(magrittr); require(tidyr)
data_dir <- "anika/bed"

file_names <- c("merged_plot_RGL") 
x <- fread("merged_plot_RGL", header = TRUE)  
secondary_files <- paste0(data_dir,"/bed_chr_", unique(x[, chr]), ".bed")  
bed_files <- lapply(secondary_files, fread)
xx <- rbindlist(bed_files)
xx2 <- x %>%
  inner_join(xx, by = c("rs_id" = "V4")) 
xx3 <- xx2 %>% 
  select(gene_id, chr, rs_id, pvalue_G, pvalue_E, V2, V3) 
xx4 <- xx3 %>%
  unite(snp, chr, V3, remove = FALSE)
names(xx4)[6] <- "pvalue"
fwrite(xx4, "ready_plot_sg.txt", quote = "F", col.names = TRUE, row.names = FALSE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...