Включая пределы обнаружения и / или метаданные неравенства в R - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть большой и сложный набор данных о качестве воды, который я пытаюсь импортировать из шоу ужасов Excel в R. Большинство переменных имеют различные биты метаданных, связанные с ними. Часть этого имеет смысл поместить в отдельный столбец (например, column1 = Magnesium; column2 = Magnesium.method), тогда как другие метаданные имеет смысл привязывать непосредственно к значению наблюдения (например, единицы измерения, пределы обнаружения). Единицы просты благодаря пакету "юнитов" fantasti c, но пределы обнаружения должны, по-видимому, также быть привязаны непосредственно к наблюдению, однако я не знаю, как лучше это сделать.

Давайте скажем, у нас есть результат, который вернулся ниже предела обнаружения, равного 6. В большинстве случаев то, что я ищу, выглядит примерно так (хотя, по-видимому, на самом деле не используется attr ()):

Value1 <- NA
attr(Value1, "Lower detection limit") <- 6
Value1
[1] NA
Conservative value:
[1] 6
Mid-range value:
[1] 3
Lowest value:
[1] 0
set_conservativeness("mid")
Value1 + 1
[1] 4
set_conservativeness("low")
Value1 +1
[1] 1

Кажется, это должно быть очень распространенной проблемой, но я не смог найти ни одного R-пакета, который бы ее решал. Возможно, я просто лаю не то дерево, что хочу, чтобы оно было атрибутом значения, а не дополнительного столбца.

1 Ответ

1 голос
/ 29 апреля 2020

Я действительно считаю, что это хорошая идея - хранить данные и метаданные вместе. Это также звучит так, как будто вы хотите иметь некоторые определенные c методы, которые вы также можете применять к измерениям.

По сути, вы описываете создание своего собственного класса. Есть несколько способов создать свой собственный класс в R. Самый простой - это, вероятно, создать класс S3.

Это предполагает наличие функции конструктора, которая позволяет вам устанавливать измерения, единицы измерения и диапазоны, которые он хранится как атрибуты возвращаемого объекта. Вам также понадобятся метод format, метод print и метод as.data.frame, а также любые пользовательские функции, которые вы хотите применить к классу.

Вот довольно наивный, но функциональный пример:

Measurement <- function(x, units = "mmol/l", range_min = 0, range_max = Inf)
{
  structure(x, class = "Measurement", units = units, 
            range_min = range_min, range_max = range_max)
}

format.Measurement <- function(x, ...)
{
  paste0(as.numeric(x), " ", attr(x, "units"), 
         " [", attr(x, "range_min"), " - ", attr(x, "range_max"), "]")
}

print.Measurement <- function(x, quote = FALSE)
{
  print(format(x), quote = quote)
}

as.data.frame.Measurement <- function(x, ...)
{
  structure(list(x), class = c("data.frame"), row.names = c(NA, length(x)))
}

Итак, теперь вы можете создать вектор из Measurement значений, например:

M <- Measurement(c(1.2, 3.6, 4.5, 2.0, 2.1, NA), units = "pmol/l", 0.1, 10)
M
#> [1] 1.2 pmol/l [0.1 - 10] 3.6 pmol/l [0.1 - 10] 4.5 pmol/l [0.1 - 10]
#> [4] 2 pmol/l [0.1 - 10]   2.1 pmol/l [0.1 - 10] NA pmol/l [0.1 - 10]

и сохранить их во фрейме данных:

data.frame(Measurement = M, ID = LETTERS[1:6])
#>             Measurement ID
#> 1 1.2 pmol/l [0.1 - 10]  A
#> 2 3.6 pmol/l [0.1 - 10]  B
#> 3 4.5 pmol/l [0.1 - 10]  C
#> 4   2 pmol/l [0.1 - 10]  D
#> 5 2.1 pmol/l [0.1 - 10]  E
#> 6  NA pmol/l [0.1 - 10]  F

Создано в 2020-04-29 пакетом Представить (v0.3.0)

...