我有一个较大的数据帧(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

09-03 23:32