在导入其他数值时处理 "less than" 和 "greater than" 符号的最佳做法是什么?

What's best practice when handling "less than" and "greater than" symbols when importing otherwise numeric values?

这是关于最佳实践的一般性问题。

我正在使用 tidyverse 包从 CSV 导入、读取然后操作临床实验室数据。对于临床数据,通常使用 "less than" 或 "greater than" 符号报告超出量化限值的值,例如 <250 mg/dL 或 >2500 mg/dL。因此,您通常会有一列主要包含数值,但 readr 会将一些值解释为字符串。如果我强制该列为数字,默认情况下字符串将被强制为 NA。

我希望能够告诉 readr 或 dplyr 接受这些字符串值(例如 <250、>2500)作为数值,删除字符(例如 250、2500)。理想情况下,这将在管道中完成。

一般来说,处理这种情况最灵活、最一致的方法是什么?

相信其中一个软件包来了解"<250 mg/dL"的意思超出了他们的专业领域。例如,根据您的需要,该值可能表示 "effectively 0""effectively 250" 或其他。这是否适用于药物或抗体或化学品或其他任何东西,它绝对是上下文。

鉴于此,我认为 programmer/analyst 有责任确定什么是合适的。

执行此操作的基本 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

整洁的版本:

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

data.table 也很容易,适应上面的 lapply


然而,这只是假定 <250250 相同,并没有区分 "real" 值和 "less than" 值。考虑:

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

如何区分第 3 行和其他行?为此,我认为您需要合并更多逻辑,也许 ifelse(grepl("<", s), "0", s) 等。同样,这都是上下文相关的,因此只有分析师知道解释这些数字时应遵循哪些规则。