sqldf в R сравнивает два фрейма данных и сохраняет выходные данные

#r #dataframe #for-loop #lapply #sqldf

#r #фрейм данных #для цикла #lapply #sqldf

Вопрос:

Итак, у меня есть около 500 файлов данных .txt, все они содержат 8 столбцов. Каждый файл данных имеет в каждом столбце одинаковое количество значений (строк). Если вы сравниваете файл данных 1 и файл данных 2, то они в основном имеют разное количество строк, но некоторые из этих значений строк совпадают, а некоторые — нет. Я хочу найти все значения, которые отличаются между datafile1 и datafile1 1= datafile2, которые я уже решил с помощью sqldf.

сначала я загружаю все файлы с помощью lapply

list_of_files <- list.files(path = ".", recursive = TRUE, pattern = "\.txt$",
full.names =TRUE)

DT <- lapply(list_of_files, read.table)

загрузите все файлы данных, чтобы первый файл данных можно было выбрать с помощью DT[[1]], а второй — с помощью DT[[1 1]], что было бы подходящим для цикла.

Для DT я хочу сравнить только столбцы V4 и V5 каждого файла данных, и я подумал, что смогу выполнить цикл с помощью DT[[i]] и DT[[i 1]] , но я не смог заставить его работать. Ниже я покажу, что сработало для DT[[1]] и DT[[2]] . Сначала я создал data.frames, который содержал оба столбца V4 и V5 соответствующих data.frames:

dt1<-data.frame(DT[[1]]$V4,DT[[1]]$V5)

dt2<-data.frame(DT[[1 1]]$V4,DT[[1 1]]$V5)

Здесь я выбираю только значения, которые отличаются между dt1 и dt2:

df<-sqldf('SELECT * FROM dt1 EXCEPT SELECT * FROM dt2')

Я хотел бы выполнить цикл действия df по всем 500 файлам данных DT[[i]] DT[[i 1]] сохранить все значения df в data.frame

Может быть, у кого-нибудь есть идея, как это сделать?

заранее спасибо

Ответ №1:

Создайте функцию :

 get_data<- function(dt1, dt2) sqldf('SELECT * FROM dt1 EXCEPT SELECT * FROM dt2')
 

Теперь используйте Map , чтобы применить эту функцию к циклу и применить ее к каждому DT[i] и DT[i 1]

 result <- Map(get_data, DT[-length(DT)], DT[-1])
 

Ответ №2:

Большое спасибо, отлично работает! Я знал, что кто-то это узнает! Результат, выводимый на данный момент, содержит в вашем решении все столбцы от V1 до V8. Если вам нужны только определенные столбцы, вы можете изменить функцию, как показано ниже:

rm(list=ls())

library(sqldf)

setwd("Path_to_txt-files")

list_of_files <- list.files(path = ".", recursive = TRUE,pattern = "\.txt$",full.names = TRUE)

DT <- lapply(list_of_files, read.table)

dt1<-data.frame(DT[[25]]$V4,DT[[25]]$V5)

dt2<-data.frame(DT[[25 1]]$V4,DT[[25 1]]$V5)

# df<-sqldf('SELECT * FROM dt1 EXCEPT SELECT * FROM dt2') не используется, если вы хотите выполнить цикл по нескольким файлам

результат вывода будет содержать только столбцы V4 и V5:

get_data<- function(dt1, dt2) sqldf('SELECT V4,V5 FROM dt1 EXCEPT SELECT V4,V5 FROM dt2')

result <- Map(get_data, DT[-length(DT)], DT[-1])

result