Что лучше всего использовать при обработке символов «меньше» и «больше» при импорте значений чисел c? - PullRequest
0 голосов
/ 04 мая 2020

Это общий вопрос о наилучшей практике.

Я использую пакеты tidyverse для импорта, чтения и манипулирования данными клинической лаборатории из CSV. С клиническими данными обычно сообщают значения за пределами количественного определения с символами «меньше» или «больше чем», например, <250 мг / дл или> 2500 мг / дл. Таким образом, у вас часто будет столбец с в основном числовыми значениями c, но несколько значений, которые readr будет интерпретировать как строки. Если я заставлю этот столбец иметь число c, по умолчанию строки приводятся к NA.

Я бы хотел сказать readr или dplyr принять эти строковые значения (например, < 250,> 2500) в качестве числовых значений c, пропуская символы (например, 250, 2500). В идеале это должно быть сделано в конвейере.

В общем, какой самый гибкий и последовательный способ справиться с этой ситуацией?

1 Ответ

2 голосов
/ 04 мая 2020

Доверие одному из пакетов, чтобы узнать, что "<250 mg/dL" означает , выходит за рамки их компетенции. Например, в зависимости от ваших потребностей это значение может означать "эффективно 0" или "эффективно 250" или что-то еще. Независимо от того, относится ли это к лекарствам, антителам, химическим веществам или чему-то еще, это абсолютно контекстуально.

Учитывая это, я думаю, что ответственность за то, что уместно, лежит на программисте / аналитике.

База R метод для этого, предполагая, что 2:3 отражает столбцы, которые вам нужно исправить:

dat <- read.csv(text = csv, stringsAsFactors = FALSE)
str(dat)
# 'data.frame': 2 obs. of  3 variables:
#  $ id  : int  1 2
#  $ val1: chr  "<250 mg/dL" ">250 mg/dL"
#  $ val2: chr  ">2500 mg/dL" "<2500 mg/dL"

dat[,2:3] <- lapply(dat[,2:3], function(s) as.numeric(gsub("[^-.0-9]", "", s)))
str(dat)
# 'data.frame': 2 obs. of  3 variables:
#  $ id  : int  1 2
#  $ val1: num  250 250
#  $ val2: num  2500 2500

Tidyversion:

library(dplyr)
readr::read_csv(csv) %>%
  mutate_at(vars(val1, val2), ~ as.numeric(stringr::str_replace_all(., "[^-.0-9]", "")))

data.table тоже легко адаптировать lapply выше.


Однако это просто предполагает, что <250 - это то же самое, что и 250, что не отличает "реальные" значения от значений "меньше чем". Подумайте:

csv <-'
id,val1,val2
1,"<250 mg/dL",">2500 mg/dL"
2,">250 mg/dL","<2500 mg/dL"
3,25,2500'

Как следует отличать строку 3 от других? Для этого, я думаю, вам нужно включить больше логи c, возможно ifelse(grepl("<", s), "0", s), et c. Опять же, все это контекстуально, поэтому только аналитик знает, какие правила должны go интерпретировать эти числа.

...