【问题标题】:Save list within data.table to csv and load it back (R)将 data.table 中的列表保存到 csv 并将其加载回来 (R)
【发布时间】:2020-04-30 09:32:37
【问题描述】:

我有一个包含列表列的 data.table。这是一个我需要编写每个会话的表,因此在重新打开应用程序后我可以回到最近的状态。

表格如下:

data.table(`ID Universal` = character(), StartDate = as.Date(character()), EndDate = as.Date(character()), 
                      BOX = character(), `Days in Period` = numeric(), 
                      `Workdays in Period` = integer(), `Present Workdays in Period` = integer(), 
                      `Days not present in Period` = list())

我尝试使用strsplit解决的写作部分:

dt.absent <- data.table(do.call("rbind", strsplit(as.character(global$dt.requests$`Days not present in Period`), ",")))
dt.req_csv <- cbind(global$dt.requests[, -8], dt.absent)
write.csv(dt.req_csv, "Requests.csv", row.names = FALSE)

这个过程似乎按预期工作(也可以替代),但加载部分我无法工作。我想加载 csv,使它看起来就像原始 data.table(我使用默认的 YYYY-mm-dd 日期格式)

【问题讨论】:

  • 如果您只是要将其加载回 R 中,您是否有理由不能使用 saveRDS 将其保存为 R 对象?

标签: r list csv shiny data.table


【解决方案1】:

然后您必须像 rds 文件一样保存数据,而不是 csv。当您使用fread 时,您会丢失因子变量,有时还会丢失日期。

只需将其保存为 RDS 文件并像这样重新加载即可。

saveRDS(object, "file.rds")
object <- readRDS("file.rds")

【讨论】:

    【解决方案2】:

    由于我们没有看到data.table 的实际内容,因此很难推测您所说的“看起来就像” 究竟是什么意思。我猜这是阅读期间的POSIXt/Date。这是使用read.csv(..., colClasses=) 的解决方法。

    ### create a file
    write.csv(data.table(rn=100L, nowdt=Sys.Date(), nowpsx=Sys.time()), "~/StackOverflow/WietsedeVries.csv", row.names=F)
    readLines("~/StackOverflow/WietsedeVries.csv")
    # [1] "\"rn\",\"nowdt\",\"nowpsx\""        "100,2020-01-13,2020-01-13 08:55:56"
    

    (注意POSIXt 的输出受到options(digits.secs) 的影响。)

    阅读:

    str(read.csv("~/StackOverflow/WietsedeVries.csv"))
    # 'data.frame': 1 obs. of  3 variables:
    #  $ rn    : int 100
    #  $ nowdt : Factor w/ 1 level "2020-01-13": 1
    #  $ nowpsx: Factor w/ 1 level "2020-01-13 08:55:56": 1
    str(read.csv("~/StackOverflow/WietsedeVries.csv", colClasses=c(nowdt="Date", nowpsx="POSIXct")))
    # 'data.frame': 1 obs. of  3 variables:
    #  $ rn    : int 100
    #  $ nowdt : Date, format: "2020-01-13"
    #  $ nowpsx: POSIXct, format: "2020-01-13 08:55:56"
    

    (我认为data.table::fread 尚不支持POSIXctDate 的功能。)


    注意事项:

    • readLines 输出中可以看出,时间戳不包含任何时区信息。如果您只是担心日期,那么这不是问题。如果您总是总是 总是在同一个时区进行交易(例如,一切都是“UTC”),那么这不是问题。但是,对于其他所有内容,您需要输入更多代码来编码时区信息。这降低了使用colClasses= 的简单性(因为它将使用as.POSIXct 而没有format="...",因此您必须在read.csv(..., colClasses=c(nowpsx="character")) 之后手动处理该列)。

    • 既然您说“每次会话后写入”,您可能会考虑改用某种数据库。如果您想保持简单,那么RSQLite 仍然只需要文件系统上的单个外部文件,并且您可以使用数据库支持的数据集比使用 CSV 做更多的事情。虽然 SQLite 本身没有完美的时间/日期类,但我相信 DBI/RSQLite 组合可以很好地完成您大部分时间需要的工作。关于这一点,您可能希望至少再包含两列:一些唯一的 id(可能是一个递增的整数)和一个“创建”时间戳,仅用于保存记录。

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 2015-10-18
      • 2021-05-01
      • 2013-10-20
      • 1970-01-01
      • 2018-02-02
      • 2022-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多