替换第n次连续出现的值

时间:2018-04-02 13:47:02

标签: r dataframe replace

我想替换数据框中第n个连续出现的特定代码。这应该是一个相对容易的任务,但我想不出解决方案。

给定数据框

df <- data.frame(Values = c(1,4,5,6,3,3,2),
                 Code = c(1,1,2,2,2,1,1))

我想要一个结果

df_result <- data.frame(Values = c(1,4,5,6,3,3,2),
                        Code = c(1,0,2,2,2,1,0))

数据框是按时间排序的,因此我需要在替换值后保持相同的顺序。我想nth()duplicate()函数在这里很有用,但我不知道如何使用它们。我缺少的是一个可以计算给定值连续出现次数的函数。一旦我拥有它,我就可以用它来代替第n次出现。 This question有一些我探索过的想法,但仍未解决我的问题。

修改

在@Gregor的回答后,我编写了以下解决问题的函数

library(data.table)
library(dplyr)

replace_nth <- function(x, nth, code) {
  y <- data.table(x)
  y <- y[, code_rleid := rleid(y$Code)]
  y <- y[, seq := seq_along(Code), by = code_rleid]
  y <- y[seq == nth & Code == code, Code := 0]
  drop.cols <- c("code_rleid", "seq")
  y %>% select(-one_of(drop.cols)) %>% data.frame() %>% return()
}

要获得解决方案,只需运行replace_nth(df, 2, 1)

即可

1 个答案:

答案 0 :(得分:1)

使用data.table

library(data.table)
setDT(df)
df[, code_rleid := rleid(df$Code)]
df[, seq := seq_along(Code), by = code_rleid]
df[seq == 2 & Code == 1, Code := 0]
df
#    Values Code code_rleid seq
# 1:      1    1          1   1
# 2:      4    0          1   2
# 3:      5    2          2   1
# 4:      6    2          2   2
# 5:      3    2          2   3
# 6:      3    1          3   1
# 7:      2    0          3   2

你可以将其中一些组合起来(然后删除额外的列)。我会说清楚,让你随意修改。