【问题标题】:Using multiple data frames to introduce new variables into each other R使用多个数据框将新变量相互引入 R
【发布时间】:2018-03-14 14:37:32
【问题描述】:

我有三个数据帧(Df1、Df2、Df3)。这些数据框有一些共同的变量,但它们也各自包含一些独特的变量。我想确保所有变量都表示在所有数据帧中,例如材料存在于 Df2 中但不存在于 Df1 中,所以我想在 Df1 中创建一个名为材料的变量并将该变量设置为 NA。谢谢你的帮助。

起点(dfs):

Df1 <- data.frame("color"=c(1,1,1),"price"=c(1,1,1),"buyer"=c(1,1,1))
Df2 <- data.frame("color"=c(1,1,1),"material"=c(1,1,1),"size"=c(1,1,1))
Df3 <- data.frame("color"=c(1,1,1),"price"=c(1,1,1),"key"=c(1,1,1))

期望的结果(dfs):

Df1 <- data.frame("color"=c(1,1,1),"price"=c(1,1,1),"material"=c(NA,NA,NA),"buyer"=c(1,1,1),"size"=c(NA,NA,NA),"key"=c(NA,NA,NA))
Df2 <- data.frame("color"=c(1,1,1),"price"=c(NA,NA,NA),"material"=c(1,1,1),"buyer"=c(NA,NA,NA),"size"=c(1,1,1),"key"=c(NA,NA,NA))
Df3 <- data.frame("color"=c(1,1,1),"price"=c(1,1,1),"material"=c(NA,NA,NA),"buyer"=c(NA,NA,NA),"size"=c(NA,NA,NA),"key"=c(1,1,1))

到目前为止我的代码:(我正在尝试将单个数据框中的变量名称与所有三个数据框中的变量名称进行比较,并使用单个数据框中不存在的变量来生成新的变量集到 NA。但我最终得到: VarDf1 [,NewVariables]

dfs <- list(Df1,Df2,Df3)  
numdfs <- length(dfs)
for (i in 1:numdfs) 
{
  VarDf1 <- as.vector(names(Df1)) 
  VarDf2 <- as.vector(names(Df2))
  VarDf3 <- as.vector(names(Df3))
  VarAll <- c(VarDf1, VarDf2,VarDf3)
  NewVariables <- as.vector(setdiff(VarAll, dfs[i]))  
  dfs[i][ , NewVariables] <- NA
}

【问题讨论】:

    标签: r


    【解决方案1】:

    plyr 包中的rbind.fill 可以满足您的期望,同时还将所有内容组合到一个大数据框架中:

    plyr::rbind.fill(Df1,Df2,Df3)
      color price buyer material size key
    1     1     1     1       NA   NA  NA
    2     1     1     1       NA   NA  NA
    3     1     1     1       NA   NA  NA
    4     1    NA    NA        1    1  NA
    5     1    NA    NA        1    1  NA
    6     1    NA    NA        1    1  NA
    7     1     1    NA       NA   NA   1
    8     1     1    NA       NA   NA   1
    9     1     1    NA       NA   NA   1
    

    您可以将数据子集化回新的 data.frames。

    【讨论】:

      【解决方案2】:

      这是基础 R 中的一种方法

      获取所有数据框中的列名

      cols = unique(unlist(lapply(list(Df1,Df2,Df3), FUN = colnames)))
      

      添加用 NA 填充的缺失列

      lapply(list(Df1,Df2,Df3), function(x){
        for (i in cols[!cols %in% colnames(x)]){
          x[[i]] = NA
        } 
        return(x)
      }
      )
      
      #output
      [[1]]
        color price buyer material size key
      1     1     1     1       NA   NA  NA
      2     1     1     1       NA   NA  NA
      3     1     1     1       NA   NA  NA
      
      [[2]]
        color material size price buyer key
      1     1        1    1    NA    NA  NA
      2     1        1    1    NA    NA  NA
      3     1        1    1    NA    NA  NA
      
      [[3]]
        color price key buyer material size
      1     1     1   1    NA       NA   NA
      2     1     1   1    NA       NA   NA
      3     1     1   1    NA       NA   NA
      

      数据:

      Df1 <- data.frame("color"=c(1,1,1),"price"=c(1,1,1),"buyer"=c(1,1,1))
      Df2 <- data.frame("color"=c(1,1,1),"material"=c(1,1,1),"size"=c(1,1,1))
      Df3 <- data.frame("color"=c(1,1,1),"price"=c(1,1,1),"key"=c(1,1,1))
      

      【讨论】:

        【解决方案3】:

        我们可以创建一个函数add_cols,并将该函数应用于所有数据帧。

        # Create a list to store all data frames
        Df_list <- list(Df1, Df2, Df3)
        
        # Get the unique name of all data frame
        Cols <- unique(unlist(lapply(Df_list, colnames)))
        
        # Create a function to add columns
        add_cols <- function(df, cols){
          new_col <- cols[!cols %in% colnames(df)]
          df[, new_col] <- NA
          return(df)
        }
        
        # Use lapply to apply the function
        Df_list2 <- lapply(Df_list, add_cols, Cols)
        
        # View the results
        Df_list2
        [[1]]
          color price buyer material size key
        1     1     1     1       NA   NA  NA
        2     1     1     1       NA   NA  NA
        3     1     1     1       NA   NA  NA
        
        [[2]]
          color material size price buyer key
        1     1        1    1    NA    NA  NA
        2     1        1    1    NA    NA  NA
        3     1        1    1    NA    NA  NA
        
        [[3]]
          color price key buyer material size
        1     1     1   1    NA       NA   NA
        2     1     1   1    NA       NA   NA
        3     1     1   1    NA       NA   NA
        

        【讨论】:

          【解决方案4】:

          这个方法类似于rbind.fill,但它会让你在最后将它分成3个数据框。

          我们使用tibble::lst 而不是list,因此列表的名称变为“Df1”、“Df2”和“Df3”。

          bind_rowsrbind.fill 做同样的事情,但是我们可以指定一个.id 列将行链接到其原始数据框。使用该列,我们可以将split这个数据框变成3。

          library('tidyverse')
          
          lst(Df1, Df2, Df3) %>%
            bind_rows(.id = 'df_id') %>%
            split(.$df_id)
          # $Df1
          #   df_id color price buyer material size key
          # 1   Df1     1     1     1       NA   NA  NA
          # 2   Df1     1     1     1       NA   NA  NA
          # 3   Df1     1     1     1       NA   NA  NA
          # 
          # $Df2
          #   df_id color price buyer material size key
          # 4   Df2     1    NA    NA        1    1  NA
          # 5   Df2     1    NA    NA        1    1  NA
          # 6   Df2     1    NA    NA        1    1  NA
          # 
          # $Df3
          #   df_id color price buyer material size key
          # 7   Df3     1     1    NA       NA   NA   1
          # 8   Df3     1     1    NA       NA   NA   1
          # 9   Df3     1     1    NA       NA   NA   1
          

          split 如果你更喜欢“整洁”的函数,也可以这样写。

          lst(Df1, Df2, Df3) %>%
            bind_rows(.id = 'df_id') %>%
            group_by(df_id) %>%
            nest %>%
            deframe
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-01-25
            • 2011-01-06
            • 2020-02-15
            • 2021-04-25
            • 2016-12-09
            • 2020-09-07
            • 2021-10-05
            • 2014-04-15
            相关资源
            最近更新 更多