Как извлечь с помощью фильтра dplyr по первому столбцу таблицы в БД sqlite
Я пытаюсь извлечь информацию из таблицы sqlite с помощью dplyr
,
Norway <- tbl(conn, "own_fleet") %>% (mmsi==235060247) %>% filter(timestamp>='2018-08-16T00:00:01') %>% collect()
Это приводит к ошибке:
Error in eval(rhs, env, env) : object 'mmsi' not found
тем не мение mmsi
существует в таблице и является первым столбцом, который я подтвердил, запустив PRAGMA table_info(own_fleet)
,
sqlite> PRAGMA table_info(own_fleet);
0|mmsi|INTEGER|0||0
1|lat|REAL|0||0
2|lon|REAL|0||0
3|rateOfTurn|INTEGER|0||0
4|sogKts|REAL|0||0
5|cog|REAL|0||0
6|heading|REAL|0||0
7|timestamp|TEXT|0||0
8|imoNumber|INTEGER|0||0
9|dimensionToBow|INTEGER|0||0
10|dimensionToStern|INTEGER|0||0
11|dimensionToPort|INTEGER|0||0
12|dimensionToStarboard|INTEGER|0||0
13|etaMonth|INTEGER|0||0
14|etaDay|INTEGER|0||0
15|etaHour|INTEGER|0||0
16|etaMinute|INTEGER|0||0
17|draught|INTEGER|0||0
18|name|TEXT|0||0
19|destination|TEXT|0||0
20|callsign|TEXT|0||0
Также timestamp
хранится как символьная переменная в таблице. Есть ли способ конвертировать его в формат даты с помощью скажем ymd_hms()
от lubridate
внутри filter()
от dplyr
?
1 ответ
У меня были похожие сообщения об ошибках при попытке подключения к базе данных. Из этих примеров я обошел проблему, используя
dplyr::collect()
до правонарушения и/или .
Сделайте некоторые образцы данных и запишите их в новую базу данных:
library(tidyverse)
library(lubridate)
library(RSQLite)
library(dbplyr)
# make a sample table, with dates
tibble(
datetime = seq(ymd_hms('2020-03-11 12:00:00'), ymd_hms('2020-03-30 12:00:00'), by = '5 days'),
id = 1:4
) %>%
mutate_all(as.character) %>%
{. ->> my_data}
my_data
# # A tibble: 4 x 2
# datetime id
# <dttm> <int>
# 1 2020-03-11 12:00:00 1
# 2 2020-03-16 12:00:00 2
# 3 2020-03-21 12:00:00 3
# 4 2020-03-26 12:00:00 4
# make database
conn <- DBI::dbConnect(RSQLite::SQLite(), 'my_database.sqlite')
# add data to the database
DBI::dbWriteTable(conn, 'my_data', my_data, overwrite = TRUE)
Получить таблицу из базы данных; обратите внимание, что я сохранил дату и время в символьном формате, чтобы предотвратить их преобразование в числовой формат при сохранении в базу данных:
# retrieve database
my_database <- tbl(conn, 'my_data')
my_database
# # Source: table<my_data> [?? x 2]
# # Database: sqlite 3.37.0 [\\Ucstaff\dfs\Associated Organisations\Institute for Applied
# # Ecology\Personnel\ALLAN\Masters\r\projects\shiny apps\cotter acoustic project\cotter acoustic project_1-5\my_database.sqlite]
# datetime id
# <chr> <chr>
# 1 2020-03-11 12:00:00 1
# 2 2020-03-16 12:00:00 2
# 3 2020-03-21 12:00:00 3
# 4 2020-03-26 12:00:00 4
Тогда, если мы попробуем и
datetime
столбец с использованием , мы получаем ошибку.
my_database %>%
mutate(
datetime = ymd_hms(datetime)
)
# Error: no such function: ymd_hms
Ошибка предполагает, что R не может найти
ymd_hms()
функция от
lubridate
, поэтому я попытался явно вызвать его:
my_database %>%
mutate(
datetime = lubridate::ymd_hms(datetime)
)
# Error in lapply(list(...), .num_to_date) : object 'datetime' not found
Эта ошибка предполагает, что столбец не существует, что странно.
Точно так же использование возвращает неожиданные результаты, чем при фильтрации обычного
data.frame
или же . Обычно я считаю, что вы можете указать число в качестве фильтра для столбца символов без проблем (я предполагаю, что R должен преобразовать одно или другое, чтобы найти совпадения), но это, похоже, не работает с подключением к базе данных.
my_database %>%
filter(
id == 2
)
# Source: lazy query [?? x 2]
# Database: sqlite 3.37.0 [\\Ucstaff\dfs\Associated Organisations\Institute for Applied
# Ecology\Personnel\ALLAN\Masters\r\projects\shiny apps\cotter acoustic project\cotter acoustic project_1-5\my_database.sqlite]
# ... with 2 variables: datetime <chr>, id <chr>
## no results
my_database %>%
filter(
id == '2'
)
# # Source: lazy query [?? x 2]
# # Database: sqlite 3.37.0 [\\Ucstaff\dfs\Associated Organisations\Institute for Applied
# # Ecology\Personnel\ALLAN\Masters\r\projects\shiny apps\cotter acoustic project\cotter acoustic project_1-5\my_database.sqlite]
# datetime id
# <chr> <chr>
# 1 2020-03-16 12:00:00 2
Таким образом, мы можем обойти эти проблемы, используя
collect()
до
filter()
или же
mutate()
, который извлекает данные в локальный
tibble
. Я предполагаю, что это означает, что вы работаете локально, а не через базу данных, но это один из способов обойти это.
my_database %>%
collect %>%
filter(
id == 2
)
# # A tibble: 1 x 2
# datetime id
# <chr> <chr>
# 1 2020-03-16 12:00:00 2
my_database %>%
collect %>%
mutate(datetime = ymd_hms(datetime))
# # A tibble: 4 x 2
# datetime id
# <dttm> <chr>
# 1 2020-03-11 12:00:00 1
# 2 2020-03-16 12:00:00 2
# 3 2020-03-21 12:00:00 3
# 4 2020-03-26 12:00:00 4