#r
#r
Вопрос:
Я пытаюсь объединить два фрейма данных по дате в 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] <- значение[[n]] : замена имеет нулевую длину».
У кого-нибудь есть идеи, как я могу это исправить?
Редактировать:
# 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")
Комментарии:
1. Вместо того, чтобы делиться
head(df1)
, можете ли вы поделитьсяdput(head(df1))
? Это расскажет нам, как именно закодированы ваши значения, и позволит нам скопировать / вставить код в R, чтобы запустить его самостоятельно.2. Возможно, это обман чего-то, но это не обман этого вопроса: единственное упоминание
class
в этом вопросе и ответах на него содержится в сравнительном анализе, а не в качестве проблемы. В остальном вопрос касается правильного использованияmerge
и ожидания его возвращаемого значения.3. Приношу свои извинения, если я неправильно истолковал вопрос / статус dupe, это не было преднамеренным.
4. Я не открываю его назло тебе, акрун, просто указываю, почему я снова открыл его, несмотря на твое закрытие.
5. здесь также это не намеренно. Я обнаружил, что слияние является очень часто задаваемым вопросом. Поправьте меня, если я ошибаюсь. Обычно я не проверяю, кто написал ответ, прежде чем заменять тег
Ответ №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
Я рискну и скажу, что class
ваши Day
столбцы отличаются.
При использовании «необработанных данных», скопированных из вопроса, 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
Исправления включают:
-
Преобразование другого фрейма
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
-
Преобразование обоих
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
(поскольку, в конце концов, это числовой тип данных).