从另一个数据帧r中添加/减去数据帧行

时间:2019-03-28 17:50:40

标签: r dplyr

我确定以前已经有人问过这个问题,但是我很难找到它。我需要将数据帧子集为一行,并从相应的列中减去这些值。

我实际上确实找到了Subtract values of a single row from all relevant columns in a data frame,它提供了一种解决方案(请参阅下文),但是必须有一种更简单的方法,对吗?一个tidyverse解决方案将非常受人们欢迎。

样本

这是一个示例数据框:

df <- as_tibble(matrix(1:9, 3, 3))
## A tibble: 3 x 3
#     V1    V2    V3
#  <int> <int> <int>
#1     1     4     7
#2     2     5     8
#3     3     6     9

减去相等大小的数据帧没问题。

df - df
#  V1 V2 V3
#1  0  0  0
#2  0  0  0
#3  0  0  0

问题

但是,当我将df子集划分为一行并尝试相减时,它无法减去不均匀的数据帧。我将df的子集设置为

df[1, ]
## A tibble: 1 x 3
#     V1    V2    V3
#  <int> <int> <int>
#1     1     4     7

我想要的解决方案是从第一列的每个值中减去1,从第二列的每个值中减去4,从第三列的每个值中减去7,这就是结果:

## A tibble: 3 x 3
#     V1    V2    V3
#  <int> <int> <int>
#1     0     0     0
#2     1     1     1
#3     2     2     2

尝试此操作将导致错误:

df - df[1, ]
#Error in Ops.data.frame(df, df[1, ]) : 
#  ‘-’ only defined for equally-sized data frames

在上面的链接中,我找到了可行的解决方案:

as_tibble(Map(`-`, df, df[1, ]))
## A tibble: 3 x 3
#     V1    V2    V3
#  <int> <int> <int>
#1     0     0     0
#2     1     1     1
#3     2     2     2

但是此解决方案似乎真的很复杂,并且不容易集成到一系列管道中。

有人有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我们可以在数据集的col索引中复制行基础。这使两个数据集具有相同的长度/维度

df - unlist(df[1,])[col(df)]
#   V1 V2 V3
#1  0  0  0
#2  1  1  1
#3  2  2  2

如果我们需要tidyverse选项,则可以使用map2

library(purrr)
library(dplyr)
map2_df(df, df[1, ], `-`)
# A tibble: 3 x 3
#     V1    V2    V3
#  <int> <int> <int>
#1     0     0     0
#2     1     1     1
#3     2     2     2

或者另一个选择是uncount

df - uncount(df[1, ], nrow(df))

或使用管道

df %>% 
  slice(1) %>% 
  uncount(nrow(df)) %>%
  {df - .}
#  V1 V2 V3
#1  0  0  0
#2  1  1  1
#3  2  2  2

或与mutate_all

df %>%
    mutate_all(list(~ . - first(.)))
# A tibble: 3 x 3
#     V1    V2    V3
#  <int> <int> <int>
#1     0     0     0
#2     1     1     1
#3     2     2     2

答案 1 :(得分:0)

如果您只是想减去data.frame的第一行,那么最好考虑只从每一列中减去第一值。您可以使用dplyr

轻松完成此操作
library(dplyr)
df %>% mutate_all(~.-first(.))