我正在尝试根据事件的发生率替换数据框中的值。在列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
答案 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][]