我正在使用 R 中的数据集,其中每一行代表单个使用服务的位置。这还隐式地跟踪某人是否使用服务,因为如果他们不使用服务,则该月的列值为 NA。我想根据连续月份列之间的转换来识别个人服务中存在中断(缺勤然后返回)的情况。
换句话说,我特别感兴趣的是确定某人何时从使用服务(一个月的列中有值)转变为不使用服务(1+ 后续月份的值是“NA”),然后又回到使用服务( 1+ 个后续月份列中的值,前面是 NA)。我希望有一个二进制 TRUE/FALSE 列(“Breaks_in_Service”)。当有人开始提供服务时并不重要(这意味着 NA 仅在第一个月列之后才重要)。
这是我的数据集的简化版本:
# Sample Data
simp_2021 <- data.frame(
ID = c(1, 2, 3, 4, 5),
jan21_ORG_NAME = c("Org A", NA, NA, "Org B", "Org B"),
feb21_ORG_NAME = c(NA, "Org A", "Org B", NA, "Org B"),
mar21_ORG_NAME = c(NA, NA, "Org B", "Org D", NA),
apr21_ORG_NAME = c("Org B", NA, "Org C", NA, "Org E")
)
# Initialize Breaks_in_Service column as FALSE
simp_2021$Breaks_in_Service <- FALSE
# View
print(simp_2021)
在示例数据中,对于 ID 1、4 和 5,Breaks_in_Service 应为 TRUE,对于 ID 2 和 3,Breaks_in_Service 应为 FALSE。
我尝试构建一个 for 循环,但它变得混乱并且不起作用:
# Loop over each row to check for breaks in service
for (i in 1:nrow(simp_2021)) {
row_values <- simp_2021[i, 2:ncol(simp_2021)] # Extract service columns for the current row
# Initialize flags to track service usage
in_service <- FALSE
found_break <- FALSE
# Check transitions within the row
for (j in 1:(length(row_values) - 1)) {
current_value <- row_values[[j]]
next_value <- row_values[[j + 1]]
if (is.na(current_value) && !is.na(next_value)) {
# Transition from not using service to using service
in_service <- TRUE
} else if (!is.na(current_value) && is.na(next_value)) {
# Transition from using service to not using service
if (in_service) {
found_break <- TRUE
break # Found a break, no need to check further
}
}
}
# Set Breaks_in_Service based on found breaks
if (found_break) {
simp_2021$Breaks_in_Service[i] <- TRUE
}
}
# View the updated dataframe with the new 'Breaks_in_Service' column
print(simp_2021)
任何帮助将不胜感激!
对于某些向量
x
x <- c("Org A", NA, NA, "Org B")
可以计算非 NA 值的“行程编码”
> rle(!is.na(x))
Run Length Encoding
lengths: int [1:3] 1 1 2
values : logi [1:3] FALSE TRUE FALSE
如果服务出现中断,则会有超过 1 个 TRUE 值。所以这是一个测试服务中断的函数
break_in_service <- function(x)
sum(rle(!is.na(x))$value) > 1
您希望为每个 ID 执行此操作。我使用 dplyr,但还有其他方法。步骤是
library(tidyr); library(dplyr)
simp_2021 |>
## convert to 'long' format
pivot_longer(ends_with("ORG_NAME")) |>
## identify the groups in your data
group_by(ID) |>
## summarize each group
summarize(has_break_in_service = break_in_service(value))
结果是
> simp_2021 |>
+ ## convert to 'long' format
+ pivot_longer(ends_with("ORG_NAME")) |>
+ ## identify the groups in your data
+ group_by(ID) |>
+ ## summarize each group
+ summarize(has_break_in_service = break_in_service(value))
# A tibble: 5 × 2
ID has_break_in_service
<dbl> <lgl>
1 1 TRUE
2 2 FALSE
3 3 FALSE
4 4 TRUE
5 5 TRUE