IlB*_*rdo 4 error-handling for-loop r dataframe rollapply
我有一个大数据帧(df),二项式值范围从1到2.NAs也包含在数据中.作为一个实际例子,我将创建一个包含用户数据子集的短向量:
df <- c(NA,NA,2,1,1,1,2,1,2,2,1,1,1,NA,2,2,1,2,1,1,1,2)
Run Code Online (Sandbox Code Playgroud)
作为结果我基本上喜欢的是一个函数,它搜索2数组的第一个和第二个s,并将此区间内的所有内容转换为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)
Run Code Online (Sandbox Code Playgroud)
该功能应具有以下结果:
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)
Run Code Online (Sandbox Code Playgroud)
请注意,在df_outcome第一个和第二个2之间的值未合并,因为它们的位置差异> 3.另一方面,其他非2值也相应地改变.
我试图做的(但它不能正常工作):
rollapply在zoo包的帮助下,我尝试创建一个函数,找到数组的第一个和第二个,并执行如上所述的修改.
func <- function (q) {
for (i in (which(q %in% 2)[1]):(which(q %in% 2)[2])) {
q[i]<-2
}
return(q)
}
Run Code Online (Sandbox Code Playgroud)
然后我使用嵌套它,rollapply因此我可以为每个循环指定一个特定的宽度加上其他参数,例如结果索引的位置(左).
df_outcome<-rollapply(df, width = 3, FUN = func, fill = NA, partial = TRUE, align = "left")
Run Code Online (Sandbox Code Playgroud)
问题是如果应用于向量,则用户生成的函数可以工作.当嵌套为函数中的rollapply参数时,它会返回错误:
错误((%(%)中的q%[1]):(其中(%2中的q%)[2]):NA/NaN参数来自:FUN(数据[替换(posns,!ix,0)) ],...)
我想我在使用rollapply或者数据格式方面存在一些错误,但我无法理解可能存在的问题.我考虑使用,rollapply因为我的数据很长,并且是为不同的用户生成的.因此,我需要一个函数,它也可以将数据与其他变量分开,例如User_ID(很像.variablesin ddply或byin中的参数)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)
Run Code Online (Sandbox Code Playgroud)
这使:
> 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
Run Code Online (Sandbox Code Playgroud)
你可以尝试获取2in 的索引df.然后得到那些位置之间的差异,从而找到要替换的值的索引2:
# position of the 2s
pos_df_2 <- which(df==2)
# which of the difference in positions are less than 3
wh_pos2_inf3 <- which(c(FALSE, diff(pos_df_2)<=3))
# get all indices between positions that are separated by less than 3 elements
ind_to_replace <- unique(unlist(sapply(wh_pos2_inf3, function(x) {pos_df_2[x-1]:pos_df_2[x]})))
# replace the elements by 2
df[ind_to_replace] <- 2
df
#[1] NA NA 2 1 1 1 2 2 2 2 1 1 1 NA 2 2 2 2 1 1 1 2
Run Code Online (Sandbox Code Playgroud)