列值位移维护模式

Column values displacement maintaining pattern

我有以下 df(有很多列)。我如何强制所有值都从 1 开始,并保持每个 ID 的模式?示例:

 input <- data.frame(ID = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3),
  Obs1 = c(1,1,1,2,2,4,4,5,6,7,2,3,4,4),
  Obs2 = c(2,2,3,4,5,1,1,1,1,1,1,1,2,2),
  Obs3 = c(5,6,7,8,9,3,3,3,4,4,1,1,2,2))

想要的结果

result <- data.frame(ID = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3),
  Obs1 = c(1,1,1,2,2,1,1,2,3,4,1,2,3,3),
  Obs2 = c(1,1,2,3,4,1,1,1,1,1,1,1,2,2),
  Obs3 = c(1,2,3,4,5,1,1,1,2,2,1,1,2,2))

我们可以按 'ID' 分组,然后 match 所有其他列的值及其 unique

library(dplyr)
result <- input %>% 
             group_by(ID) %>%
             mutate_all(funs(match(., unique(.))))

all.equal(result, result1, check.attributes = FALSE)
#[1] TRUE

按ID分组,然后减去每组内每列的最小值(-1):

library(dplyr)

input %>%
    group_by(ID) %>%
    mutate_at(vars(Obs1, Obs2, Obs3), funs(. - min(.) + 1))