从列 R 中的所有条目中减去列的最大值

subtract max of column from all entries in column R

我的数据框如下所示:

kfm <- data.frame ("data_source"=c("kfm", "kfm", "kfm", "kfm"), 
               "1996"= c(56, 56, 56, 57), 
               "1997"=c(8, 8, 9, 7),
               "1998"= c(101, 102, 101, 105))

我想从每一年的列中减去每一列的最大值(在我的数据框中我有大约 20 年)。因此,如果 1996 年的最大值为 57。那么我想从 1996 年的每个条目中减去 57。 1997 年的最大值是 9,所以我想从 1997 年的每个条目中减去 9。我希望生成的数据框看起来像:

kfm_differences <- data.frame ("data_source"=c("kfm", "kfm", "kfm", "kfm"), 
               "1996"= c(-1, -1, -1, 0), 
               "1997"=c(-1, -1, 0, -2),
               "1998"= c(-4, -3, -4, 0))

因此每个条目现在显示最大值与条目之间的差异。我不知道该怎么做。我觉得我需要以某种方式使用 apply(),但我不太确定。

谢谢!

解决方案

kfm_differences = data.frame(data_source = kfm$data_source, mapply("-", kfm[-1], lapply(kfm[-1], max)))
#> kfm_differences
#  data_source X1996 X1997 X1998
#1         kfm    -1    -1    -4
#2         kfm    -1    -1    -3
#3         kfm    -1     0    -4
#4         kfm     0    -2     0

说明

  • 我们得到每列的最大值 lapply(kfm[-1], max)
  • 然后我们使用 mapply("-", kfm[-1], lapply(kfm[-1], max))
  • kfm 的每一列中减去这些值中的每一个
  • 最后,我们使用 data.frame(data_source = kfm$data_source, mapply("-", kfm[-1], lapply(kfm[-1], max)))
  • data_source 列正确命名来构建结果 data.frame

看起来很简单。

kfm_differences <- kfm
kfm_differences[-1] <- lapply(kfm[-1], function(x) x - max(x))

顺便说一句,当创建列名以数字开头的数据框时,使用参数check.names = FALSE,否则R会附加一个X.

这可以使用 approach as well with the mutate_if verb from 来完成。

dplyr::mutate_if(kfm, is.numeric, funs(. - max(.)))

#   data_source X1996 X1997 X1998
# 1         kfm    -1    -1    -4
# 2         kfm    -1    -1    -3
# 3         kfm    -1     0    -4
# 4         kfm     0    -2     0