如何通过基于某些逻辑准则选择选定的值来合并数据帧?

问题描述

我有3个结构相似的数据帧,并尝试在逻辑条件的基础上用前3个数据帧中的值填充第4个数据帧。

我的数据框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

请求有关如何合并的帮助。

解决方法

在出现问题的情况下,您必须按行绑定所有数据框。之后,您可以使用tidyverse函数来按帐户ID定义的组进行过滤。下面是使用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)),-3L))

#Data 3
df3 <- structure(list(Account.id = 1:3,2000L,5000L
),RMSE = c(10,25,0.2)),-3L))
,

带有data.table

的选项
library(data.table)
rbindlist(list(df1,df3))[,.(Value = Value[which.min(RMSE)]),.(Account.id)]
#   Account.id Value
#1:          1   400
#2:          2  7000
#3:          3  5000

或者在将数据集与tidyverse绑定在一起之后,使用slice_minbind_rows

library(dplyr)
bind_rows(df1,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,-3L))

df2 <- structure(list(Account.id = 1:3,-3L))

df3 <- structure(list(Account.id = 1:3,-3L))
,

R的基本选项正在使用merge + aggregate

merge(
  df <- do.call(rbind,lst(df1,df3)),aggregate(RMSE ~ Account.id,df,min)
)[c("Account.id","Value")]

给出

  Account.id Value
1          1   400
2          2  7000
3          3  5000