Как я могу использовать do.call () для чтения определенных строк? - PullRequest
1 голос
/ 14 мая 2019

Я использую команду do.call (), чтобы прочитать список csv-файлов, чтобы все точки данных были в одном csv-файле. Я использовал следующее:

files = list.files(path = "G:/SafeGraph201708MidWest",
                     pattern = "*.csv",
                     recursive = TRUE,
                     full.names = TRUE)

library(data.table)
  DT = do.call(rbind, lapply(files, fread))

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

Data <- filter(DT, longitude >= -86.97 & longitude <= -86.78, 
                 latitude >= 40.35 & latitude <= 40.49)

Есть ли способ сделать это, используя do.call ()? Ждем скорого ответа. Спасибо!

Ответы [ 3 ]

3 голосов
/ 14 мая 2019

Есть несколько стратегий, как справиться с этим. Вы можете импортировать все данные в список, используя lapply, а затем отфильтровать каждый элемент списка на основе вашего фильтра. Вы бы использовали data.table::rbindlist, чтобы сделать окончательный data.table. Другим было бы сделать это за один шаг, например, (не проверено, очевидно)

library(data.table)

files = list.files(path = "G:/SafeGraph201708MidWest",
                   pattern = "*.csv",
                   recursive = TRUE,
                   full.names = TRUE)

xy <- lapply(files, FUN = function(x) {
  out <- fread(x)
  out <- filter(out, longitude >= -86.97 & longitude <= -86.78, 
                latitude >= 40.35 & latitude <= 40.49)
  out
})

xy <- rbindlist(xy)
1 голос
/ 14 мая 2019

Предполагая, что вы используете компьютер с ОС Windows и у вас установлен хотя бы Microsoft Office 2007+, рассмотрите возможность прямого запроса CSV-файла с помощью JET / ACE SQL Engine (файлы .dll), который является ядром MS Access.

Ниже приведены две строки подключения с использованием Access или Excel.Любая версия работает, и файлы должны существовать, но никогда не используются, кроме как для подключения к ACE.После подключения файлы CSV запрашиваются по тому же или другому пути.

library(odbc)

# VERIFY AVAILABLE DSNs AND DRIVERS
odbcListDataSources()

# DSN VERSIONS
conn <- dbConnect(odbc::odbc(), DSN ="MS Access Database;DBQ=C:\\Path\\To\\Access.accdb;");
conn <- dbConnect(odbc::odbc(), DSN ="Excel Files;DBQ=C:\\Path\\To\\Excel.xlsx;");

# DRIVER VERSIONS
conn <- dbConnect(odbc::odbc(), 
                  .connection_string = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=C:\\Path\\To\\Access.accdb;");    
conn <- dbConnect(odbc::odbc(), 
                  .connection_string ="Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=C:\\Path\\To\\Excel.xlsx;");

# CSV QUERY
df <- dbGetQuery(conn, "SELECT t.* 
                        FROM [text;database=C:\\Path\\To\\CSV_Folder].Name_of_File.csv AS t 
                        WHERE t.longitude BETWEEN -86.97 AND -86.78
                          AND t.latitude BETWEEN 40.35 AND 40.49;")    
head(df)

dbDisconnect(conn)

И в цикле:

files = list.files(path = "G:/SafeGraph201708MidWest",
                   pattern = "*.csv",
                   recursive = TRUE,
                   full.names = TRUE)    

df_list <- lapply(files, function(f)    
    df <- dbGetQuery(conn, 
                     paste0("SELECT t.* ",
                            " FROM [text;database=G:\\SafeGraph201708MidWest].", f, " AS t ",
                            " WHERE t.longitude BETWEEN -86.97 AND -86.78", 
                            "   AND t.latitude BETWEEN 40.35 AND 40.49;")
                    )    
)

final_dt <- rbindlist(df_list)
0 голосов
/ 15 мая 2019

Вы можете использовать способность из data.table::fread(), чтобы выполнить команду и «прочитать» полученный результат.

Я предполагаю, что вы используете Windows, поэтому у вас есть доступ к findstr -функции в командной строке.

Таким образом, если вы можете построить регулярное выражение, которое «попадает» в строки, которые вы хотите извлечь, вы можете отфильтровать нужные строки перед чтением всего файла в R. Это (потенциально) огромная экономия памяти для больших файлов, и может значительно ускорить ваш рабочий процесс.

образец данных

lat говорит, чтоordins.csv выглядит так:

id,latitude,longitude
1,10,11
2,11,12
3,12,13
4,13,14
5,14,15

В этом примере вы хотите извлечь строки с широтами между 12 и 14 и долготами между 11 и 13

код

#build a list of files (I created only one)
#make sure you use the full path (not relative)
x <- list.files( path = "C:/folder", pattern = "coord.csv", full.names = TRUE )

#build reges that only hits on rows with:
#  latitude 12-14
#  longitude 11-13
pattern = "^[0-9],1[2-4],1[1-3]$"

#read the file(s), extract the lines with match the regex-pattern 
#and bind the resuklt to a data.table
rbindlist( lapply( x, function(x) { 
  fread( cmd = paste0( "findstr /R ", pattern, " ", x ), header = FALSE ) 
} ) )

выход

    V1 V2 V3
 1:  3 12 13
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...