【问题标题】:Trouble combining double and character麻烦结合双和字符
【发布时间】:2022-01-08 03:49:18
【问题描述】:

我在合并数据集时遇到问题,我打算将许多数据集合并在一起,因此需要找出一种方法来自动解决以下错误:

"Error: Can't combine `C:/Users/gabri/AppData/Local/Cache/R/noaa_lcd/2006_72038163885.csv$HourlyWetBulbTemperature` <double> and `C:/Users/gabri/AppData/Local/Cache/R/noaa_lcd/2009_72038163885.csv$HourlyWetBulbTemperature` <character>."

我检查了数据,发现其中一个文件中的一些 NA 用 * 标记,所以我知道这就是问题所在。我想添加一个命令,将全部转换为字符或全部转换为数字,以便我可以合并,但是当我尝试添加 as.character 时,我收到此错误:

Error: Names repair functions can't return `NA` values

这是我尝试运行的相关代码,它会产生错误。

library(rnoaa)
library(tidyverse)
library(fs)

super_big_df <- map_df(my_files, read_csv, col_select = c(1,2,21,32,80), col_types = "cTddd", .id = "file")

这里是数据集相关列的 dput 输出

structure(list(STATION = c(72038163885, 72038163885, 72038163885
), DATE = structure(c(1230768000, 1230769200, 1230770400), tzone = "UTC", class = c("POSIXct", 
"POSIXt")), HourlyWetBulbTemperature = c("*", "38", "37"), DailyAverageWetBulbTemperature = c(NA, 
NA, NA), MonthlyWetBulb = c(NA, NA, NA)), row.names = c(NA, -3L
), class = c("tbl_df", "tbl", "data.frame"))
structure(list(STATION = c(72038163885, 72038163885, 72038163885
), DATE = structure(c(1146459600, 1146460800, 1146462000), tzone = "UTC", class = c("POSIXct", 
"POSIXt")), HourlyWetBulbTemperature = c(NA_real_, NA_real_, 
NA_real_), DailyAverageWetBulbTemperature = c(72, NA, NA), MonthlyWetBulb = c(NA, 
NA, NA)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", 
"data.frame"))

总之,我想知道是否有一个命令可以放入 map_df() 中,它将所有内容都转换为相同的(字符或数字),以便命令的其余部分仍然运行。

【问题讨论】:

  • 在关闭后问同样的问题,实际上没有任何变化,这通常是一个坏主意,可能会引发其他人的强烈反应。虽然“我们”(社区)没有通过扩展密切原因(“需要详细信息”)为您提供出色的服务,但我希望您能推断出我们在不知道文件内容的情况下无能为力。您的问题与组合框架有关,因此您通过要求我们检查 NOAA 查询的内容来添加不必要的麻烦;而且由于我没有安装该软件包,因此没有发生。
  • 请阅读可重现的问题(stackoverflow.com/q/5963269、minimal reproducible example 和 stackoverflow.com/tags/r/info),然后用样本数据提出问题,以便我们专注于手头的问题。这可能最好对对象使用dput(x)(其中x 是较大对象的一个​​小且具有代表性的样本),或者通过将文本文件的第一行n 发布到一个代码块(n 是主观的,但请确保您提供给我们的示例以同样的方式正确“失败”)。
  • 我建议你自己删除这个问题暂时;这将防止在您改进问题时投反对票。删除后,您仍然可以随意edit,进行建议的更改,然后在您再次准备好时取消删除。当你这样做时,请@ping我,我会来看看。谢谢!
  • 与该问题直接相关的唯一信息是有问题的两列。显然一个是character 类,一个是numeric(双)。代替 60 多个字母的长名称,我们将数据框称为 df1 和 df2。您应该查看character 列df2$HourlyWetBulbTemperature 的一些内容,以了解为什么它是字符而不是数字。也许添加一个新列df2$HWBT_numeric &lt;- as.numeric(df2$HourlyWetBulbTemperature) 并查看numeric 版本为NA 的行以查看原始值中无法转换的值......
  • 处理它们的最佳时间是导入文件时。大多数导入命令都有一个名为na.strings 或na 或类似名称的参数,可让您指定可被视为NA 的值。因此,将"*" 添加到该默认值中,它应该可以正确读取您的数据,并解决这些下游问题。

标签: r merge


【解决方案1】:

未经测试,但正如@GregorThomas 建议的那样,最好的方法是第一次正确阅读它。在这种情况下,可能是这样的:

super_big_df <- map_df(
  my_files, read_csv, na = c("", "NA", "*"),
  col_select = c(1,2,21,32,80), col_types = "cTddd",
  .id = "file")

如果您需要事后修复它,那么您需要将它们读入list-of-frames,也许将map_df 更改为map,

super_big_df <- map(
  my_files, read_csv, na = c("", "NA", "*"),
  col_select = c(1,2,21,32,80), col_types = "cTddd",
  .id = "file")
bind_rows(super_big_df)
# Error: Can't combine `..1$HourlyWetBulbTemperature` <character> and `..2$HourlyWetBulbTemperature` <double>.

然后是类似的东西

library(dplyr) # in case you did not already have it loaded
purrr::map(super_big_df, ~ mutate(., HourlyWetBulbTemperature = suppressWarnings(as.numeric(HourlyWetBulbTemperature)))) %>%
  bind_rows()
# # A tibble: 6 x 5
#       STATION DATE                HourlyWetBulbTemperature DailyAverageWetBulbTemperature MonthlyWetBulb
#         <dbl> <dttm>                                 <dbl>                          <dbl> <lgl>         
# 1 72038163885 2009-01-01 00:00:00                       NA                             NA NA            
# 2 72038163885 2009-01-01 00:20:00                       38                             NA NA            
# 3 72038163885 2009-01-01 00:40:00                       37                             NA NA            
# 4 72038163885 2006-05-01 05:00:00                       NA                             72 NA            
# 5 72038163885 2006-05-01 05:20:00                       NA                             NA NA            
# 6 72038163885 2006-05-01 05:40:00                       NA                             NA NA            

这里的suppressWarnings 是因为我们知道在那一列的某处有一个非数字("*")。对于那一帧,它将修复该列;对于其他帧,它应该是空操作,因为该列已经是 as.numeric。

请注意,我在这里对名称进行了硬编码,因为我们提前知道它是什么。如果有更多列需要修复(即,修复此列后出现更多错误),那么采用更动态/程序化的方法可能是有利的(此处尚未介绍)。


数据

super_big_df <- list(
  structure(list(STATION = c(72038163885, 72038163885, 72038163885), DATE = structure(c(1230768000, 1230769200, 1230770400), tzone = "UTC", class = c("POSIXct", "POSIXt")), HourlyWetBulbTemperature = c("*", "38", "37"), DailyAverageWetBulbTemperature = c(NA, NA, NA), MonthlyWetBulb = c(NA, NA, NA)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame")),
  structure(list(STATION = c(72038163885, 72038163885, 72038163885), DATE = structure(c(1146459600, 1146460800, 1146462000), tzone = "UTC", class = c("POSIXct", "POSIXt")), HourlyWetBulbTemperature = c(NA_real_, NA_real_, NA_real_), DailyAverageWetBulbTemperature = c(72, NA, NA), MonthlyWetBulb = c(NA, NA, NA)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"))
)

【讨论】:

  • Gabriela Nagle,这对你有用吗?
  • 很高兴它成功了,Gabriele Nagle。由于您是新来的……不急,但是当您对答案解决了您的问题感到满意时,请accept it(出于多种原因,在此处列出)。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 2020-09-16
  • 2014-10-19
相关资源
最近更新 更多