【问题标题】:Substracting Two Dataframes - Retaining first Column containing names as characters减去两个数据框 - 保留包含名称作为字符的第一列
【发布时间】:2021-07-19 14:07:19
【问题描述】:

对于我正在尝试做的事情,我还没有找到确切的答案。我经常要减去两个数据框,每个数据框都包含一个“名称”列。示例:

df1 <- data.frame(name = c("name1","name2","name3","name4"),
                  month1 = c(5,6,7,8),
                  month2 = c(10,11,12,13),
                  month3 = c(15,16,17,18))

df2 <- data.frame(name = c("name1","name2","name3","name4"),
                  month1 = c(22,23,24,25),
                  month2 = c(31,34,35,39),
                  month3 = c(42,43,45,46))

我非常想做的是有一个 df3,它是 df2 - df1 的减法,但保留名称列:


df3 <- df1 %>%
  select("name")

temp <- df2[,-c(1)] - df1[,-c(1)]

df3 <- bind_cols(df3,temp) 

print(df3)

   name month1 month2 month3
1 name1     17     21     27
2 name2     17     23     27
3 name3     17     23     28
4 name4     17     26     28

现在,只有短短的三行代码。但是,是否没有“单行”函数可以在指定保留“名称”列的同时减去数据帧。它本质上与 df2[,-c(1)] - df1[,-c(1)] 的作用相同,但会立即重新添加“名称”列,而不是拆分数据框。这可能吗?

【问题讨论】:

    标签: r dataframe dplyr


    【解决方案1】:

    您的解决方案已经接近于单线。通过不同的写法,你可以使它像这样单行:

    bind_cols(name = df1$name, df2[,-1] - df1[,-1])                  
    

    但我认为这并不是真正的改进,因为您正在失去原始解决方案的一些可读性。

    你是说你经常这样做。自己为此编写一个函数,然后可以重复使用可能是个好主意。

    subtract_dfs <- 
      function(df1, df2, name = "name") {
        bind_cols(name = df1[name], df2[,-1] - df1[,-1])                  
      }
    

    现在你可以这样做了:

    subtract_dfs(df1, df2)
    

    这允许名称变量具有自定义值。功能还可以进一步完善。例如,即使不是 name 的所有值都存在于两个数据帧中,它也可以扩展以提供正确的结果。

    【讨论】:

    • 谢谢,您的第一个建议正是我想要的!我会尝试函数方法,这是我真正需要进入的东西。我经常做那个操作,但是在不同的数据帧上。我的意思是它们通常具有相同的尺寸和整体结构。无论如何,谢谢!
    【解决方案2】:

    您可以使用 dplyr 和 purrr:

    library(dplyr)
    library(purrr)
    
    map2_dfc(df2[-1], df1[-1], ~ .x - .y) %>% cbind(df2[1], .)
    
       name month1 month2 month3
    1 name1     17     21     27
    2 name2     17     23     27
    3 name3     17     23     28
    4 name4     17     26     28
    
    

    您也可以将其包装在自定义函数中:

    subtract_dfs<-function(df_1, df_2){
        purrr::map2_dfc(df_1[-1], df_2[-1], ~ .x - .y) %>% cbind(df_1[1], .)
        }
    

    编辑

    这里不需要映射函数,因为数据帧可以一次全部减去:

    cbind(df2[1], df2[-1] - df1[-1])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-22
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-29
      • 2017-02-20
      • 1970-01-01
      相关资源
      最近更新 更多