在 R 中寻找值和 NA 的行序列中的中断模式

问题描述 投票:0回答:1

我正在使用 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)

任何帮助将不胜感激!

r data-cleaning sequential
1个回答
0
投票

对于某些向量

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
© www.soinside.com 2019 - 2024. All rights reserved.