#r #dataframe #merge #logical-operators #forecasting
#r #фрейм данных #слияние #логические операторы #прогнозирование
Вопрос:
У меня есть 3 фрейма данных с аналогичной структурой, и я пытаюсь заполнить 4-й фрейм данных значениями из первых 3 фреймов данных, но на основе логических условий.
Мой фрейм данных 1
`Account id Value $ RMSE
1 500 10
2 7000 15
3 1900 20
Мой фрейм данных 2
`Account id Value $ RMSE
1 400 5
2 8000 18
3 1700 18
Мой фрейм данных 3
`Account id Value $ RMSE
1 500 10
2 2000 25
3 5000 0.2
Мой желаемый результат (значение, полученное из фрейма данных, который имеет наименьший соответствующий RMSE)
`Account id Value $
1 400
2 7000
3 5000
Просим вашей помощи о том, как объединить.
Ответ №1:
В случае вашей проблемы вам необходимо связать все ваши фреймы данных по строкам. После этого вы можете использовать tidyverse
функции для фильтрации по группе, определенной идентификатором учетной записи. Здесь код с tidyverse
подходом:
library(tidyverse)
#Code
ndf <- do.call(bind_rows,list(df1,df2,df3)) %>%
group_by(Account.id) %>%
filter(RMSE==min(RMSE)) %>% select(Account.id,Value) %>%
arrange(Account.id)
Вывод:
# A tibble: 3 x 2
# Groups: Account.id [3]
Account.id Value
<int> <int>
1 1 400
2 2 7000
3 3 5000
Некоторые используемые данные:
#Data 1
df1 <- structure(list(Account.id = 1:3, Value = c(500L, 7000L, 1900L
), RMSE = c(10L, 15L, 20L)), class = "data.frame", row.names = c(NA,
-3L))
#Data 2
df2 <- structure(list(Account.id = 1:3, Value = c(400L, 8000L, 1700L
), RMSE = c(5L, 18L, 18L)), class = "data.frame", row.names = c(NA,
-3L))
#Data 3
df3 <- structure(list(Account.id = 1:3, Value = c(500L, 2000L, 5000L
), RMSE = c(10, 25, 0.2)), class = "data.frame", row.names = c(NA,
-3L))
Ответ №2:
Опция с data.table
library(data.table)
rbindlist(list(df1, df2, df3))[, .(Value = Value[which.min(RMSE)]), .(Account.id)]
# Account.id Value
#1: 1 400
#2: 2 7000
#3: 3 5000
Или с tidyverse
использованием slice_min
после связывания наборов данных вместе с bind_rows
library(dplyr)
bind_rows(df1, df2, df3) %>%
group_by(Account.id) %>%
slice_min(RMSE) %>%
select(-RMSE)
# A tibble: 3 x 2
# Groups: Account.id [3]
# Account.id Value
# <int> <int>
#1 1 400
#2 2 7000
#3 3 5000
df1 <- structure(list(Account.id = 1:3, Value = c(500L, 7000L, 1900L
), RMSE = c(10L, 15L, 20L)), class = "data.frame", row.names = c(NA,
-3L))
df2 <- structure(list(Account.id = 1:3, Value = c(400L, 8000L, 1700L
), RMSE = c(5L, 18L, 18L)), class = "data.frame", row.names = c(NA,
-3L))
df3 <- structure(list(Account.id = 1:3, Value = c(500L, 2000L, 5000L
), RMSE = c(10, 25, 0.2)), class = "data.frame", row.names = c(NA,
-3L))
Ответ №3:
Базовая опция R использует merge
aggregate
merge(
df <- do.call(rbind, lst(df1, df2, df3)),
aggregate(RMSE ~ Account.id, df, min)
)[c("Account.id","Value")]
что дает
Account.id Value
1 1 400
2 2 7000
3 3 5000