Как адаптировать функцию замены строк для замены определенных чисел во фрейме данных на NA? - PullRequest
0 голосов
/ 07 мая 2018

Я написал функцию, которая отлично заменяет пользовательские значения матрицы на NA.

NAfun <- function (x, z) {
  x[x %in% z] <- NA
  x
}

M <- matrix(1:12, 3, 4)
M[1, 2] <- -77
M[2, 1] <- -99
> M
     [,1] [,2] [,3] [,4]
[1,]    1  -77    7   10
[2,]  -99    5    8   11
[3,]    3    6    9   12

z <- c(-77, -99)

> NAfun(M, z)
     [,1] [,2] [,3] [,4]
[1,]    1   NA    7   10
[2,]   NA    5    8   11
[3,]    3    6    9   12

Но это не будет работать с фреймами данных.

D <- as.data.frame(matrix(LETTERS[1:12], 3, 4))
> D
  V1 V2 V3 V4
1  A  D  G  J
2  B  E  H  K
3  C  F  I  L

z <- c("B", "D")

> NAfun(D, z)
  V1 V2 V3 V4
1  A  D  G  J
2  B  E  H  K
3  C  F  I  L

D[] <- lapply(D, function(x) as.character(x))  # same with character vectors

> NAfun(D, z)
  V1 V2 V3 V4
1  A  D  G  J
2  B  E  H  K
3  C  F  I  L

Если я преобразую фрейм данных в матрицу, это сработает.

> NAfun(as.matrix(D), z)
     V1  V2  V3  V4 
[1,] "A" NA  "G" "J"
[2,] NA  "E" "H" "K"
[3,] "C" "F" "I" "L"

Но я не могу в моем случае.

Я не понимаю, почему это не будет работать так, как есть. И какой способ адаптировать функцию так, чтобы она работала с фреймом данных, или, предпочтительно, с обоими типами, спасибо.

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

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

NAfun <- function (x, z) {

     f1 <- function(x, z){
          x[x %in% z] <- NA
          x
     }
     purrr::modify(x, ~f1(., z))
}
0 голосов
/ 08 мая 2018

Как @Lyngbakr правильно упомянул, что поведение согласуется между D и M. Функция NAfun работала на D, поскольку она уже была преобразована в matrix по строке D <- sapply(D, as.character).

Итак, вопрос в том, почему поведение несовместимо между matrix и data.frame? Фактическая причина - оператор %in%.

Оператор% in% сравнивает каждое значение матрицы в векторе z как:

D %in% z
#[1] FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

, тогда как оператор% in% на data.frame сравнивает соответствующие столбцы. Следовательно,

M %in% c(-99,-77)
#[1] FALSE FALSE FALSE FALSE

Но

M %in% M[1:2]
#[1]  TRUE  TRUE FALSE FALSE

M %in% list(c(1,-99,3))
[1]  TRUE FALSE FALSE FALSE

Модификация, необходимая для функции NAfun, для обработки data.frame и matrix:

NAfun <- function (x, z) {
  x <- as.matrix(x)
  x[x %in% z] <- NA
  x
}
...