我正在研究智能手机记录数据。不幸的是,显示器上的信息是基于事件的,仅指示显示器何时打开或关闭(display_on_id1 == 1:显示器在这一秒被打开;== 0:显示器被关闭)。我想有一个额外的变量display_status
,它有关于当前显示状态的信息(0如果显示器当前被关闭,1如果它当前被打开)。对于只有一个用户的情况,我想出了一个解决方案,使用for和while循环,但是当将代码应用于具有多个案例的 Dataframe 时,这并不起作用。我还想找到一个更有效的解决方案,因为我计划将其应用于更大的 Dataframe 。
这是1个用户id的原始数据:
display_on_id1 <- c(NA, NA, NA, NA, 1, NA, NA, NA, 0, NA)
所需数据应如下所示:
display_status_id1 <- c(0, 0, 0, 0, 1, 1, 1, 1, 0, 0)
我使用以下代码实现了这一点:
# replace NA to avoid problems
library(tidyr)
display_status_id1 <- display_on_id1 %>% replace_na(999)
for (i in c(1:length(display_status))) {
n <- 1
if(display_status[i] == 1) {
while(display_status[i+n] > 0) {
display_status[i+n] <- 2
n <- n+1
}
}
}
有没有比使用循环(dplyr等)更有效的方法来解决这个问题?
下一个问题是我的数据中有多个用户,因此原始数据看起来像这样:
display_on <- data.frame(id1 = c(NA, NA, NA, NA, 1, NA, NA, NA, 0, NA),
id2 = c(NA, NA, 1, NA, NA, 0, NA, NA, NA, NA),
id3 = c(NA, 1, NA, 0, NA, NA, 1, NA, 0, NA)
)
结果应该如下所示:
display_status <- data.frame(id1 = c(0, 0, 0, 0, 1, 1, 1, 1, 0, 0),
id2 = c(0, 0, 1, 1, 1, 0, 0, 0, 0, 0),
id3 = c(0, 1, 1, 0, 0, 0, 1, 1, 0, 0)
)
我尝试使用另一个for循环来遍历display_on的列,但不幸的是,这不起作用:
display_status <- display_on %>% replace_na(999)
for(j in c(1:ncol(display_status))) {
for (i in c(1:nrow(display_status[,j]))) {
n <- 1
if(display_status[i,j] == 1) {
while(display_status[i+n,j] > 0) {
display_status[i+n,j] <- 2
n <- n+1
}
}
}
}
非常感谢你的帮助!
1条答案
按热度按时间rta7y2nd1#
你可以使用
tidyr::fill()
。基本上,你可以有两个步骤:1.向下填充值,例如从第一个
1
填充到第一个非NA
值,与0
相同,等等。1.因为我们是在
down
方向上填充的,所以我们需要用0
替换初始的NA
。创建于2023-04-11带有reprex v2.0.2