dplyr写入SQLite的日期字段读取后变为数值格式的求助
Hey there! Let's break down why your date field keeps turning into a numeric value when reading from SQLite, and how to fix it so you can filter by date ranges without first converting the entire data frame.
Why This Happens
SQLite doesn't have a native DATE data type—instead, it stores date values as numeric counts of days since 1970-01-01 (the Unix epoch). When you use dbplyr to read the table, it doesn't automatically convert these numeric values back to R's Date type by default, which is why you see those numbers like 17571 instead of formatted dates.
Solutions to Try
1. Convert Dates Directly in the Database Query (Recommended)
You don't need to pull the entire data frame into R to fix the date format. Use dbplyr to mutate the date field while it's still connected to the database, then filter your data directly. This keeps processing on the database side (faster for large datasets like yours):
# Connect to the SQLite database and convert the Date field upfront BOR <- tbl(database, "BOR") %>% mutate(Date = as.Date(Date, origin = "1970-01-01")) %>% select(RTK, Date, Day) # Now you can filter by date range directly (no need for a data frame yet) filtered_BOR <- BOR %>% filter(Date >= ymd("2018-02-01") & Date <= ymd("2018-02-10")) # If you need a data frame later, just call as.data.frame() filtered_df <- as.data.frame(filtered_BOR)
2. Specify Column Types When Writing to SQLite
When you use copy_to, you can explicitly tell SQLite to treat the Date field as a DATE type. While SQLite still stores it as a numeric value, this hint helps dbplyr recognize it as a date when reading later:
# After converting BOR$Date to R's Date type copy_to(database, BOR, temporary = FALSE, overwrite = TRUE, types = c(Date = "DATE")) # Next time you read, dbplyr should auto-convert the numeric to Date BOR <- tbl(database, "BOR") %>% select(RTK, Date, Day) str(BOR) # Should show Date type for the Date field
3. Store Dates as Text Strings (Alternative)
If you prefer, you can format dates as YYYY-MM-DD strings before writing to SQLite. This makes date comparisons straightforward in both SQLite and R:
# Convert Date to formatted text BOR$Date <- format(BOR$Date, "%Y-%m-%d") # Write to SQLite with TEXT type for Date copy_to(database, BOR, temporary = FALSE, overwrite = TRUE, types = c(Date = "TEXT")) # Read and filter using date strings or convert back to Date type BOR <- tbl(database, "BOR") %>% mutate(Date = ymd(Date)) %>% # Convert back to R Date if needed filter(Date >= ymd("2018-02-09"))
Key Takeaway
The first method is the most efficient for large datasets like yours—you avoid loading all 340k rows into R memory and handle the date conversion and filtering directly in the database.
内容的提问来源于stack exchange,提问作者Diego Spamer

