我有一个较大的数据帧(df),其二项式值的范围为1到2。NAs也包含在数据中。作为一个实际示例,我将创建一个包含用户数据子集的简短 vector :
df <- c(NA,NA,2,1,1,1,2,1,2,2,1,1,1,NA,2,2,1,2,1,1,1,2)
我基本上希望得到的结果是一个函数,该函数搜索数组的第一个和第二个
2
,并将此间隔内的所有内容转换为2。但是,如果第二个和第一个2的位置之间的差是> 3,则这些值保持不变,并且不执行任何更改。除上述内容外,该函数还必须针对
df
的每个值进行循环。例如,再次考虑以下情况:df <- c(NA,NA,2,1,1,1,2,1,2,2,1,1,1,NA,2,2,1,2,1,1,1,2)
该函数应具有以下结果:
df_outcome <- c(NA,NA,2,1,1,1,2,2,2,2,1,1,1,NA,2,2,2,2,1,1,1,2)
请注意,在
df_outcome
中,第一个和第二个2之间的值未合并,因为它们位置的差异> 3。另一方面,其他非2值也相应更改。我尝试做的事情(但无法正常工作):
借助于
rollapply
包中的zoo
,我尝试创建一个函数,该函数查找数组的第一个和第二个2并执行如上所述的修改。func <- function (q) {
for (i in (which(q %in% 2)[1]):(which(q %in% 2)[2])) {
q[i]<-2
}
return(q)
}
然后,我使用
rollapply
将其嵌套,这样我可以为每个循环指定一个特定的宽度以及其他参数,例如结果索引的位置(左)。df_outcome<-rollapply(df, width = 3, FUN = func, fill = NA, partial = TRUE, align = "left")
问题在于,如果将用户生成的函数应用于 vector ,则该函数可以工作。但是,当将其作为参数嵌套在
rollapply
函数中时,它将返回错误:我猜我在使用
rollapply
或数据格式方面存在一些错误,但我不明白可能是什么问题。我考虑使用rollapply
,因为我的数据很长并且是为不同的用户生成的。因此,我需要一个函数,该函数还可以针对其他变量(例如User_ID
)拆分数据(非常类似于.variables
中的ddply
参数或by
中的data.table
。期待您的支持。
最佳答案
使用rle
的解决方案:
rldf <- rle(df)
rllag <- c(tail(rldf$values,-1), NA)
rllead <- c(NA, head(rldf$values,-1))
rldf$values[which(rldf$values == 1 & rllag == 2 & rllead == 2 & rldf$lengths < 3)] <- 2
df_out <- inverse.rle(rldf)
这使:
> df_out
[1] NA NA 2 1 1 1 2 2 2 2 1 1 1 NA 2 2 2 2 1 1 1 2
> identical(df_outcome,df_out)
[1] TRUE