r - 如何强制将 tibble 数据框列从 double 转换为 time?
问题描述
我在tidyverse。
read_csv
我使用(都具有相同的列)读取了几个 CSV 文件
df <- read_csv("data.csv")
获取一系列数据帧。经过一堆数据清理和计算,我想合并所有数据框。
有几十个几百行和几十列的数据帧。一个最小的例子是
DF1
ID name costcentre start stop date
<chr> <chr> <chr> <time> <tim> <chr>
1 R_3PMr4GblKPV~ Geo Prizm 01:00 03:00 25/12/2019
2 R_s6IDep6ZLpY~ Chevy Malibu NA NA NA
3 R_238DgbfO0hI~ Toyota Corolla 08:00 11:00 25/12/2019
DF2
ID name costcentre start stop date
<chr> <chr> <chr> <lgl> <time> <chr>
1 R_3PMr4GblKPV1OYd Geo Prizm NA NA NA
2 R_s6IDep6ZLpYvUeR Chevy Malibu NA 03:00 12/12/2019
3 R_238DgbfO0hItPxZ Toyota Corolla NA NA NA
根据我的清洁要求(开始 == NA & stop != NA),其中的一些 NAstart
必须是00:00
. 我可以在该单元格中输入零:
df <- within(df, start[is.na(df$start) & !is.na(df$stop)] <- 0)
这导致
DF1
ID name costcentre start stop date
<chr> <chr> <chr> <time> <tim> <chr>
1 R_3PMr4GblKPV~ Geo Prizm 01:00 03:00 25/12/2019
2 R_s6IDep6ZLpY~ Chevy Malibu NA NA NA
3 R_238DgbfO0hI~ Toyota Corolla 08:00 11:00 25/12/2019
DF2
ID name costcentre start stop date
<chr> <chr> <chr> <dbl> <time> <chr>
1 R_3PMr4GblKPV1OYd Geo Prizm NA NA NA
2 R_s6IDep6ZLpYvUeR Chevy Malibu 0 03:00 12/12/2019
3 R_238DgbfO0hItPxZ Toyota Corolla NA NA NA
我在合并时遇到问题,有时start
是双重的(因为我已经做了一些替换),是合乎逻辑的(因为所有 NA 都没有替换),或者是时间(如果在原始数据读取中有一些时间)
merged_df <- bind_rows(DF1, DF2,...)
给我错误Error: Column
开始can't be converted from hms, difftime to numeric
如何强制开始列成为类型time
,以便我可以合并我的数据?
解决方案
我认为重要的一点是start和stop列似乎是time类型的,它们是基于hms包的。我想知道为什么/何时显示,因为我以前没有听说过这门课。
正如我所看到的,这些列实际上属于hms和difftime类。这些对象实际上不是在几分钟内存储(如打印的小标题所暗示的),而是在几秒钟内。如果我们通过查看数据,我们会看到这一点View(df)
。有趣的是,如果我们打印数据,变量类型显示为time。
要解决您的问题,您必须将所有开始和停止列一致地转换为 hms difftime 列,如下例所示。
最小的可重现示例:
library(dplyr)
library(hms)
df1 <- tibble(id = 1:3,
start = as_hms(as.difftime(c(1*60,NA,8*60), units = "mins")),
stop = as_hms(as.difftime(c(3*60,NA,11*60), units = "mins")))
df2 <- tibble(id = 4:6,
start = c(NA,NA,NA),
stop = as_hms(as.difftime(c(NA,3*60,NA), units = "mins")))
甚至更容易(但打印与问题略有不同):
df1 <- tibble(id = 1:3,
start = as_hms(c(1*60,NA,8*60)),
stop = as_hms(c(3*60,NA,11*60)))
df2 <- tibble(id = 4:6,
start = c(NA,NA,NA),
stop = as_hms(c(NA,3*60,NA)))
解决问题:
class(df1$start) # In df1 start has class hms and difftime
class(df2$start) # In df2 start has class logical
# We set start=0 if stop is not missing and turn the whole column into an hms object
df2 <- df2 %>% mutate(start = new_hms(ifelse(!is.na(stop), 0, NA)))
# Now that column types are consistent across tibbles we can easily bind them together
df <- bind_rows(df1, df2)
df
推荐阅读
- android - Dart:如何调用二维列表?
- angularjs - 将代码从 AngularJS 迁移到 ReactJS
- amazon-web-services - 通过 AWS API Gateway 集成模板使用 lastEvaluatedKey 扫描 DynamoDB
- java - 从 Java 的 ADFS SAML .NET 服务器获取请求令牌
- c++ - 如何获得堆栈排序的正确输出
- javascript - 使用 Vue 和 JS 下载 CSV 文件
- liquibase - 使用 liquibase 创建部分索引
- python - 如何在 django 的一个通用应用程序中组合两个不同的模板?
- php - PHPUnit 检查方法返回类型
- r - 3 条件语句在r中抛出一个长度错误