R: Вычислите сумму строк (оценка MERSQI), скорректированную на пропущенные значения / неприменимые категории

#r #dplyr #data-cleaning #missing-data

Вопрос:

Я хотел бы рассчитать суммы строк, включая поправку на недостающие данные.

Суммы строк-это баллы «MERSQI» в реальном времени (оценка качества исследований, 1 студий за строку). Каждый col — это вопрос о качестве с определенным достижимым максимумом баллов. Однако в некоторых случаях вопросы не были применимы к некоторым исследованиям, приводящим к «отсутствующим значениям». Сумма строк должна быть скорректирована до стандартного знаменателя 18 как максимальная сумма баллов/строк, т. е.: (максимальное количество достижимых баллов= сумма максимально достижимых баллов применимых вопросов/колов)

общий балл MERSQI = сумма строк / максимальное количество достижимых баллов * 18

Например:

 questions <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) #number of question or col number
max_quest <- c(3, 1.5, 1.5, 3, 1, 1, 1, 1, 3) #maximum of every single question
study1 <- c(1.5, 0.5, 1.5, 3, 0, 0, 0, 1, 3) #points for every single questions for study1
study2 <- c(1, 0.5, 0.5, 3, NA, NA, NA, 1, 1, 3) # for study2
study3 <- c(2, 1.5, NA, 3, NA, 1, NA, 1, 1, 3) #for study3
df <- rbind (questions, max_quest, study1, study2, study3)
 

Для исследования 1 у нас будет сумма строк и итоговый балл 10,5, так как отсутствующих значений нет.
Для исследования 2 у нас есть сумма строк 10. У нас есть три NA, максимально достижимые баллы для изучения2 составили 15 (=18 максимальных баллов — 3*1 балл вопросов NA), и скорректированный балл MERSQI составил 12,85 (=10 *18/15).
Для исследования 3: сумма строк= 12,5, максимально достижимые баллы=15.5 (=18 -(1.5 1 1)), скорректированный показатель MERSQI= 15,53

У вас есть какие-либо идеи о том, как рассчитать суммы строк с поправкой на пропущенные значения? Может быть, с прохождением каждой строки, использованием for цикла и if с is.na ?

Спасибо!

PS: Ссылка / объяснение для оценки MERSQI: https://www.aliem.com/article-review-how-do-you-assess/ и https://pubmed.ncbi.nlm.nih.gov/26107881/

Ответ №1:

Существует проблема с длиной векторов. Я отредактировал набор данных так, чтобы все они имели длину 9, но это должно сработать:

 apply(mat[, 3:5],
      2,
      FUN = function (x) {
        tot = sum(x, na.rm = TRUE)
        nas = which(is.na(x))
        total_max = sum(max_quest)
        if (!length(nas)) 
          return(tot)
        else
          return(tot * total_max / (total_max - sum(max_quest[nas])))
      })
 

Данные:

 questions <- c(1, 2, 3, 4, 5, 6, 7, 8, 9) #number of question or col number
max_quest <- c(3, 1.5, 1.5, 3, 1, 1, 1, 1, 3) #maximum of every single question
study1 <- c(1.5, 0.5, 1.5, 3, 0, 0, 0, 1, 3) #points for every single questions for study1
study2 <- c(1, 0.5, 0.5, 3, NA, NA, NA, 1, 1) # for study2
study3 <- c(2, 1.5, NA, 3, NA, 1, NA, 1, 1) #for study3

## rename mat because cbind(...) of vectors returns matrix.
mat <- cbind (questions, max_quest, study1, study2, study3)
 

Ответ №2:

Для каждого study столбца вычислите его sum умножение на сумму max_quest и деление на max_quest NA значение.

 library(dplyr)

val <- sum(df$max_quest)

df %>%
  summarise(across(starts_with('study'), 
            ~sum(., na.rm = TRUE)* val/(val - sum(max_quest[is.na(.)]))))
 

данные

Общие данные не являются полными из-за несовместимой длины. Также имело бы смысл, если бы эти значения располагались по столбцам, а не по строкам.

 questions <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 
max_quest <- c(3, 1.5, 1.5, 3, 1, 1, 1, 1, 3, 3)
study1 <- c(1.5, 0.5, 1.5, 3, 0, 0, 0, 1, 3, 0) 
study2 <- c(1, 0.5, 0.5, 3, NA, NA, NA, 1, 1, 3)
study3 <- c(2, 1.5, NA, 3, NA, 1, NA, 1, 1, 3)
df <- data.frame(questions, max_quest, study1, study2, study3)
 

Ответ №3:

Это можно сделать с помощью векторизации.

Сначала примените суммы строк и найдите количество NAs:

row_sums <- apply(df, 1, function(x) sum(x, na.rm=T))

row_NAs <- apply(df,1, function(x) sum(is.na(x)))

Затем вытащите исследования и наберите максимальное количество баллов:

studies <- row_sums[3:length(row_sums)]

max <- row_sums[2]

Вычислите MERSQI по скорректированному максимуму на основе NAs:

adjusted_max <- rep(max, length(studies)) - row_NAs[3:length(row_NAs)]

MERSQI <- studies * max / adjusted_max