【问题标题】:Why is merge not working with date values?为什么合并不适用于日期值?
【发布时间】:2020-08-17 20:18:55
【问题描述】:

我正在尝试在 R 中按日期合并两个数据框。
第一个数据框记录每日温度。它只有 28 行,没有重复的日期。

head(df1)

Day MaxTemp MinTemp
2019-06-15 23.8 14.4
2019-06-16 24.9 11.7
2019-06-17 23.2 8.7

第二个数据框记录每小时的温度,因此有更多行,日期重复。

head(df2)

Day Hour Temp
2019-06-15 14 22.8
2019-06-15 15 22.4
2019-06-15 16 21.9

我想将数据合并为如下所示:

Day MaxTemp MinTemp Hour Temp 
2019-06-15 14 22.8 23.8 14.4
2019-06-15 15 22.4 23.8 14.4
2019-06-15 16 21.9 23.8 14.4

但我最终得到的是:

allData <-merge(df1, df2, by="Day", all.y=T)

head(allData)

Day Hour Temp MaxTemp MinTemp
2019-06-15 14 22.8 NA NA
2019-06-15 15 22.4 NA NA
2019-06-15 16 21.9 NA NA

或者如果我在参数中尝试“all = T”,我会得到“x[[n]][i] 有谁知道我该如何解决这个问题?

编辑:

# head of df1

df1 <- structure(list(Day = structure(list(sec = c(0, 0, 0, 0, 0, 0), 
min = c(0L, 0L, 0L, 0L, 0L, 0L), hour = c(0L, 0L, 0L, 0L, 
0L, 0L), mday = 15:20, mon = c(5L, 5L, 5L, 5L, 5L, 5L), year = c(119L, 
119L, 119L, 119L, 119L, 119L), wday = c(6L, 0L, 1L, 2L, 3L, 
4L), yday = 165:170, isdst = c(1L, 1L, 1L, 1L, 1L, 1L), zone = c("CDT", 
"CDT", "CDT", "CDT", "CDT", "CDT"), gmtoff = c(NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_
)), class = c("POSIXlt", "POSIXt")), Max = c(23.8, 24.9, 23.2, 22.4, 25.1, 24.4), Min = c(14.4, 11.7, 8.7, 8.7, 9.8, 10)), row.names = c(NA, 6L), class ="data.frame")

# head of df2
df2 <- structure(list(Date = structure(list(sec = c(0, 0, 0, 0, 0, 0), 
min = c(0L,30L, 0L, 30L, 0L, 30L), hour = c(14L, 14L, 15L, 15L, 16L, 16L),
mday = c(15L, 15L, 15L, 15L, 15L, 15L), mon = c(5L, 5L, 5L, 5L, 5L, 5L), 
year = c(119L, 119L, 119L, 119L, 119L, 119L), wday = c(6L, 6L, 6L, 6L, 6L,
6L), yday = c(165L,165L, 165L, 165L, 165L, 165L), isdst = c(1L, 1L, 1L, 1L,
1L, 1L), zone =c("CDT", "CDT", "CDT", "CDT", "CDT", "CDT"), gmtoff = 
c(NA_integer_, NA_integer_, NA_integer_, NA_integer_, NA_integer_,
NA_integer_)),class = c("POSIXlt","POSIXt")), Temp = c(22.8, 22.4, 22.4, 
22.3,21.9, 21.3), Hour =c(14L, 14L, 15L, 15L, 16L, 16L), Day =
structure(c(18062,18062, 18062, 18062, 18062, 18062), class = "Date")), 
row.names= c(NA, 6L), class = "data.frame")

【问题讨论】:

  • 不分享head(df1),可以分享dput(head(df1))吗?这将准确地告诉我们您的值是如何编码的,并将让我们将代码复制/粘贴到 R 中以自己运行。
  • 这可能是一个骗局,但它不是 that 问题的骗局:在那个问题中唯一提到 class 并且它的答案在基准测试,不是问题。该问题对 merge 的其他正确用法和对其返回值的期望。
  • 如果我误解了问题/欺骗状态,我深表歉意,这不是故意的。
  • 我不是为了惹恼你而重新打开它,akrun,我只是在说明为什么尽管你关闭了它,我还是重新打开了它。
  • 这里也不是故意的。我发现合并是一个非常常见的问题。纠正我,如果我错了。在我欺骗标签之前,我通常不会检查谁写了答案

标签: r


【解决方案1】:

确认与您的dput 输出:

class(df1$Day)
# [1] "POSIXlt" "POSIXt" 
class(df2$Day)
# [1] "Date"

您需要将一个转换为另一个类,也许df1$Day 是每个值(在此集合中)的相同时间,那么您可以这样做

merge(df1, df2, by = "Day", all.y = TRUE)
#          Day Max Min                Date Temp Hour
# 1 2019-06-15  NA  NA 2019-06-15 14:00:00 22.8   14
# 2 2019-06-15  NA  NA 2019-06-15 14:30:00 22.4   14
# 3 2019-06-15  NA  NA 2019-06-15 15:00:00 22.4   15
# 4 2019-06-15  NA  NA 2019-06-15 15:30:00 22.3   15
# 5 2019-06-15  NA  NA 2019-06-15 16:00:00 21.9   16
# 6 2019-06-15  NA  NA 2019-06-15 16:30:00 21.3   16

df1$Day <- as.Date(df1$Day)

merge(df1, df2, by = "Day", all.y = TRUE)
#          Day  Max  Min                Date Temp Hour
# 1 2019-06-15 23.8 14.4 2019-06-15 14:00:00 22.8   14
# 2 2019-06-15 23.8 14.4 2019-06-15 14:30:00 22.4   14
# 3 2019-06-15 23.8 14.4 2019-06-15 15:00:00 22.4   15
# 4 2019-06-15 23.8 14.4 2019-06-15 15:30:00 22.3   15
# 5 2019-06-15 23.8 14.4 2019-06-15 16:00:00 21.9   16
# 6 2019-06-15 23.8 14.4 2019-06-15 16:30:00 21.3   16

我会说你的Day 列中的class 是不同的。

使用从问题中复制的“原始数据”,Day 将是两个框架的字符串:

df1 <- read.table(header = TRUE, text = "
Day MaxTemp MinTemp
2019-06-15 23.8 14.4
2019-06-16 24.9 11.7
2019-06-17 23.2 8.7")

df2 <- read.table(header = TRUE, text = "
Day Hour Temp
2019-06-15 14 22.8
2019-06-15 15 22.4
2019-06-15 16 21.9")

str(lapply(df1, class))
# List of 3
#  $ Day    : chr "character"
#  $ MaxTemp: chr "numeric"
#  $ MinTemp: chr "numeric"
merge(df1, df2, by = "Day")
#          Day MaxTemp MinTemp Hour Temp
# 1 2019-06-15    23.8    14.4   14 22.8
# 2 2019-06-15    23.8    14.4   15 22.4
# 3 2019-06-15    23.8    14.4   16 21.9

如果我将其中一个转换为 Date 类:

df1$Day <- as.Date(df1$Day)
str(lapply(df1, class))
# List of 3
#  $ Day    : chr "Date"
#  $ MaxTemp: chr "numeric"
#  $ MinTemp: chr "numeric"

merge(df1, df2, by = "Day", all.y = TRUE)
#          Day MaxTemp MinTemp Hour Temp
# 1 2019-06-15      NA      NA   14 22.8
# 2 2019-06-15      NA      NA   15 22.4
# 3 2019-06-15      NA      NA   16 21.9

修复包括:

  1. other 框架的 Day 转换为日期:

    df2$Day <- as.Date(df2$Day)
    merge(df1, df2, by = "Day", all.y = TRUE)
    #          Day MaxTemp MinTemp Hour Temp
    # 1 2019-06-15    23.8    14.4   14 22.8
    # 2 2019-06-15    23.8    14.4   15 22.4
    # 3 2019-06-15    23.8    14.4   16 21.9
    
  2. 将两个Day 列转换回character(或factor):

    df1$Day <- as.character(df1$Day)
    df2$Day <- as.character(df2$Day)
    merge(df1, df2, by = "Day", all.y = TRUE)
    #          Day MaxTemp MinTemp Hour Temp
    # 1 2019-06-15    23.8    14.4   14 22.8
    # 2 2019-06-15    23.8    14.4   15 22.4
    # 3 2019-06-15    23.8    14.4   16 21.9
    

    尽管在这种情况下,您很可能(甚至建议)在某个时候将它们转换回 Date(毕竟它是一种数字数据类型)。

【讨论】:

    猜你喜欢
    • 2012-11-06
    • 1970-01-01
    • 2018-06-14
    • 2015-12-17
    • 1970-01-01
    • 2016-12-23
    • 2022-10-16
    • 2021-06-18
    • 2021-12-14
    相关资源
    最近更新 更多