我确定以前已经有人问过这个问题,但是我很难找到它。我需要将数据帧子集为一行,并从相应的列中减去这些值。
我实际上确实找到了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
但是此解决方案似乎真的很复杂,并且不容易集成到一系列管道中。
有人有什么想法吗?
答案 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(.))