r - 用数据框 (R) 中的 NA 替换 X 个连续重复的零值
问题描述
我有一个数据框,其中包含几个用户的每日价值。用户有不同的开始日期,因此我为第一次使用之前的值分配了 NA,为此后没有值的任何单元格分配了零值。我使用以下循环来执行此操作:
for (i in seq_along(df)) {
isna <- is.na(df[[i]])
nonna <- match(FALSE,isna)
id <- which(isna)
df[[i]][id[id>nonna]] <- 0
}
但是,有些用户在接近尾声时有很多零值,表明他们已经停止使用该服务。如果数据帧末尾有超过 100 个零值,我也想将这些值设置为 NA。我没有成功地做到这一点,任何建议将不胜感激。
解决方案
我想我理解你的问题,所以让我重述一遍,如果我错了,你可以告诉我。
您有一个数据框,其中列代表用户,行代表天。因此,从数据框中取出一列df[[i]]
将为您提供一个用户活动的时间序列。
用户并非都在同一天开始,因此其中一些时间序列可能有很长的初始0
活动运行。这表明用户还没有使用您的服务,应该是NA
0 而不是 0。因此我们可以假设在第一个非零数字的日期之前的所有内容都应该是NA
.
一些用户在加入您的服务后的几天内有 0 个活动。这只是意味着他们那天没有使用您的服务。但是,如果他们完全离开您的服务,他们将生成一长串零,直到他们离开时的列末尾。
一些用户可能偶然在数据帧末尾有几个 0 - 他们没有离开服务,只是在数据帧停止的时间点恰好有几天没有使用它。这些 0 不应转换为NA
值。但是,如果用户在其列末尾有超过 100 天的连续零活动,则末尾的所有零都应转换为NA
.
假设这就是您的意思,并且假设NA
您的列中没有值开始,我们可以解决运行长度编码的问题。我已经评论了每一行,所以你可以遵循逻辑:
for(i in length(df))
{
user <- df[[i]] # Write the column to a new vector for clarity
MAX <- 100 # Set the maximum number of 0s allowed at the end
user_rle <- rle(user) # Get run length encoding of the column
lens <- user_rle$lengths # Extract the run-length encoding lengths
vals <- user_rle$values # Extract the run-length encoding values
last <- length(lens) # For clarity of code, make alias for last index of rle
if(vals[1] == 0) { # If zeros at the start...
user[seq(lens[1])] <- NA # Replace with NA
}
if(vals[last] == 0 & lens[last] > MAX) { # If more than 100 0s at end
user[(-lens[last] + 1):0 + length(user)] <- NA # Replace with NA
}
df[[i]] <- user # Write the vector back in to the data frame
}
请注意,有更有效的方法可以使用更少的代码来做到这一点,但这是为了易于遵循。
推荐阅读
- react-native - 使用 react-native-image-picker 从图库中删除图像
- c++ - 为什么 _Printf_format_string_ 宏不产生任何警告?
- xaml - Xamarin 表单实现带有透明切口的底栏
- java - Apache poi 迁移到 jdk 11 问题
- angular - 一次运行 2 个单独的 Kendo-UI Angular 项目(理论上就像它只是一个项目一样)
- docker - 登录到 nexus docker 注册表时出现 401 未经授权的错误
- javascript - Fusioncharts 中的可滚动 X 轴
- delphi - 如何使用任务对话框常用图标加载 TImage?
- python - 部分匹配 2 列与另一列的条件
- angularjs - ngInfinitescroll 在 Angular js 中不起作用