如何在数据框中的特定事件后替换值?

时间:2017-07-24 15:14:55

标签: r

我正在尝试根据事件的发生率替换数据框中的值。在列exp_recode中,我显示了所需的输出。 time_point显示事件的时间,指示events列中事件的时间顺序。我想在z后感兴趣的事件重新编码为0。请注意,重复id s,因为这些是纵向数据。

如果您想知道我为什么要在z之后重新编码/标记出现的情况,我打算将其删除,因为这些不是我感兴趣的事件。但是我不想在分析的这个阶段放弃它们。

id <- c(rep(1, 6),rep(2,4))
time_point <- c(1:6, 1:4)
event <- c("b","b","c","z", "d", "a", "e", "b", "z", "d")
exp_recode<- c(c("b","b","c","z", 0, 0, "e", "b", "z", 0))
df <- data.frame(id, time_point, event, exp_recode)
df
   id time_point event exp_recode
1   1          1     b          b
2   1          2     b          b
3   1          3     c          c
4   1          4     z          z
5   1          5     d          0
6   1          6     a          0
7   2          1     e          e
8   2          2     b          b
9   2          3     z          z
10  2          4     d          0

4 个答案:

答案 0 :(得分:2)

试试by。 (我花了一段时间,因为我正在尝试ave,忘记它返回一个数字向量。)

fun <- function(x){
    x <- as.character(x)
    i <- min(which(x == "z"))
    x[seq_along(x)[-seq_len(i)]] <- 0
    x
}
df$exp_recode2 <- unlist(by(df$event, df$id, FUN = fun))
df

我敢打赌,有一种更简单的dplyr方式可以做到这一点,但这只是使用基础R

答案 1 :(得分:1)

它不漂亮但它有效。 注意仅当您有一个&#34; z&#34;在一个小组中。

您的数据(stringsAsFactors=F

df <- data.frame(id, time_point, event, stringsAsFactors=F)

使用dplyr时,如果&#34; z&#34;将exp_recode设为0找到并且对于之后的值,将exp_recode更改为&#34; z&#34;何时event=="z",并在exp_recode时将event更改为exp_recode==1

library(dplyr)
df1 <- df %>%
         group_by(id) %>%
         mutate(exp_recode=1-cumsum(event=="z")) %>%
         mutate(exp_recode=ifelse(event=="z", "z", exp_recode)) %>%
         mutate(exp_recode=ifelse(exp_recode==1, event, exp_recode))

输出

      id time_point event exp_recode
 1     1          1     b          b
 2     1          2     b          b
 3     1          3     c          c
 4     1          4     z          z
 5     1          5     d          0
 6     1          6     a          0
 7     2          1     e          e
 8     2          2     b          b
 9     2          3     z          z
 10     2          4     d          0

答案 2 :(得分:1)

使用基础R match查找第一个z索引并使用0替换其后的所有内容:

zero_after_z <- function(vec) { 
    vec_len = length(vec) 
    first_z = match("z", vec, nomatch = vec_len) 
    if(first_z < vec_len) replace(vec, (first_z+1):vec_len, "0") 
    else vec 
}

zero_after_z(c("a", "b", "z", "d"))
# [1] "a" "b" "z" "0"
df$exp_recode <- with(df, ave(event, id, FUN=zero_after_z))

df
#   id time_point event exp_recode
#1   1          1     b          b
#2   1          2     b          b
#3   1          3     c          c
#4   1          4     z          z
#5   1          5     d          0
#6   1          6     a          0
#7   2          1     e          e
#8   2          2     b          b
#9   2          3     z          z
#10  2          4     d          0

答案 3 :(得分:1)

为了完整起见,这里有一个data.table解决方案,它使用非等连接更新连接,并按{{1}进行分组}}:

.EACHI
library(data.table)   # CRAN version 1.10.4 used
# coerce to data.table class, 
# coerce to character (only required if event is factor)
setDT(df)[, event := as.character(event)][
  # find all z events
  df[event == "z"], 
  # non-equi join, update all events after z event grouped by id
  on = .(id, time_point > time_point), event := "0", by = .EACHI][]