我有三个数据框,它们具有相同的列名,但顺序不同,我需要创建一个新的数据框

时间:2019-08-21 09:45:24

标签: r dataframe

我有以下格式的三个数据帧dt1,dt2和dt3:

Customer
column names : Asset A Asset B Asset C ... 
row names : dates

,并且数据由0到1的值组成,尽管它们都包含相同的列名,但是它们的顺序不同。

我需要创建一个具有相同列和行名称的新数据框,但每个数据点都等于(dt1 * 0.5)+(dt2 * 0.25)+(dt3 * 0.25)

由于只能合并两个数据框,因此我不确定如何处理此问题。

我尝试过使用mapply [intersect()...]合并一个然后合并另一个,但它并没有给我准确的结果,并且

2 个答案:

答案 0 :(得分:1)

一种快速的解决方案是重新对齐列:

c1 <- colnames(dt1)
dt1 * 0.5 + dt2[,c1] * 0.25 + dt3[,c1] * 0.25

但这还假设行的顺序相同(dt2的日期为5月31日,而其他的日期为5月30日),并且日期以行名给出(不会添加)。

答案 1 :(得分:0)

包装

library(dplyr)
library(tibble)

数据

总是提供这样一个可重现的数据示例,您可以对一部分数据使用dput函数。

df1 <- structure(
  list(
    #date = c("5/30/2019", "5/20/2019", "5/10/2019"),
    asset_a = c(0, 1, 0),
    asset_b = c(0.03, 0.23, 0.9),
    asset_c = c(0.39, 0, 0.65),
    asset_d = c(0, 0.5, 0)),
  class = "data.frame",
  row.names = c("5/30/2019", "5/20/2019", "5/10/2019"))


df2 <- structure(
  list(#date = c("5/30/2019", "5/20/2019", "5/10/2019"),
       asset_a = c(0, 0, 0.1),
       asset_c = c(0.82, 0.04, 0.1),
       asset_b = c(0.12, 0.9, 0),
       asset_d = c(0, 0, 0)),
  class = "data.frame",
  row.names = c("5/30/2019", "5/20/2019", "5/10/2019"))


df3 <-structure(
  list(
    #date = c("5/30/2019", "5/20/2019", "5/10/2019"),
    asset_a = c(0.38, 0.48, 0.49),
    asset_d = c(0, 0, 0.82),
    asset_c = c(0.1, 0.1, 0),
    asset_b = c(0.48, 0.49, 0.79)),
  class = "data.frame", row.names = c("5/30/2019", "5/20/2019", "5/10/2019"))

在合并之前,将所有列乘以其摘要

df1 <- df1 %>% rownames_to_column("date") %>% mutate_if(is.numeric, funs(.*0.5))
df2 <- df2 %>% rownames_to_column("date") %>% mutate_if(is.numeric, funs(.*0.25))
df3 <- df3 %>% rownames_to_column("date") %>% mutate_if(is.numeric, funs(.*0.25))

将行绑定在一起

要这样做,请使用dplyr::bind_rows,因为此函数将两个数据帧或一个数据帧列表作为参数并将行绑定在一起,而无论cols的顺序如何

full_df <- bind_rows(
  list(df1 = df1, df2 = df2, df3 = df3),
  .id = "df")

汇总数据

full_df %>%
  group_by(date) %>%
  summarise_if(is.numeric, sum)

所有内容都在一个管道中


list(df1 = df1, df2 = df2, df3 = df3) %>%
  purrr::map2(.x =., .y = c(0.5, 0.25, 0.25), 
       ~.x %>% 
         tibble::rownames_to_column("date") %>%
         dplyr::mutate_if(is.numeric, funs(. * .y))) %>%
  dplyr::bind_rows() %>%
  dplyr::group_by(date) %>%
  dplyr::summarise_all(sum)