Сделать значения не смежными друг с другом - PullRequest
2 голосов
/ 31 марта 2020

Значения> = 10 в приведенном ниже кадре данных (значения 31,89,12,69) иногда имеют порядок, подобный 89 и 12. Под этим я имею в виду порядок 123456789, они смежны друг с другом. Я хотел бы сделать значения, которые не являются смежными друг с другом (31,69, в 31 nr 2 отсутствует между, чтобы быть в порядке, для 69, nr 7 и 8 отсутствуют в порядке) NA. Как закодировать это? Вообразите большой набор данных! :)

 id <- factor(rep(letters[1:2], each=5))
    A <- c(1,2,NA,67,8,9,0,6,7,9)
    B <- c(5,6,31,9,8,1,NA,9,7,4)
    C <- c(2,3,5,NA,NA,2,7,6,4,6)
    D <- c(6,5,89,3,2,9,NA,12,69,8)
    df <- data.frame(id, A, B,C,D) 
    df
  id  A  B  C  D
1   a  1  5  2  6
2   a  2  6  3  5
3   a NA 31  5 89
4   a 67  9 NA  3
5   a  8  8 NA  2
6   b  9  1  2  9
7   b  0 NA  7 NA
8   b  6  9  6 12
9   b  7  7  4 69
10  b  9  4  6  8 

Это должно выглядеть так:

 id  A  B  C  D
1   a  1  5  2  6
2   a  2  6  3  5
3   a NA NA  5 89
4   a 67  9 NA  3
5   a  8  8 NA  2
6   b  9  1  2  9
7   b  0 NA  7 NA
8   b  6  9  6 12
9   b  7  7  4 NA
10  b  9  4  6  8

Ответы [ 3 ]

2 голосов
/ 31 марта 2020

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

numerals <- 1:9
vector <- 0:9
for (i in numerals) {
  j <- numerals[i+1]
  if (!is.na(j)) {
    number <- as.numeric(paste(c(i, j), collapse = ""))
    number_reverse <- as.numeric(paste(c(j, i), collapse = ""))
    vector <- c(vector, number, number_reverse)
  }
}

vector
[1]  0  1  2  3  4  5  6  7  8  9 12 21 23 32 34 43 45 54 56 65 67 76 78 87 89 98

Функция для замены числа, если не в vector:

replace <- function(x) {
  x <- ifelse(!x %in% vector, NA, x)
  return(x)
}

Результат:

df %>% mutate_at(c("A", "B", "C", "D"), replace)

   id  A  B  C  D
1   a  1  5  2  6
2   a  2  6  3  5
3   a NA NA  5 89
4   a 67  9 NA  3
5   a  8  8 NA  2
6   b  9  1  2  9
7   b  0 NA  7 NA
8   b  6  9  6 12
9   b  7  7  4 NA
10  b  9  4  6  8
2 голосов
/ 31 марта 2020

Вот функция, которая проверяет отдельные числа

MyFunction <- function(A){
  NumbersToCheck <- lapply(strsplit(as.character(A),""),as.integer)
  check <- lapply(2:length(unlist(NumbersToCheck)), function(X) ifelse(NumbersToCheck[[1]][X]-NumbersToCheck[[1]][X-1]==1,TRUE,FALSE))
  return(ifelse(FALSE %in% check,NA,A))
}

, которые затем могут быть применены ко всей вашей df следующим образом

df[,2:ncol(df)] <- lapply(2:ncol(df),  function(X) unlist(lapply(df[,X],MyFunction)))

, чтобы получить следующий результат

> df
   id  A  B  C  D
1   a  1  5  2  6
2   a  2  6  3  5
3   a NA NA  5 89
4   a 67  9 NA  3
5   a  8  8 NA  2
6   b  9  1  2  9
7   b  0 NA  7 NA
8   b  6  9  6 12
9   b  7  7  4 NA
10  b  9  4  6  8
1 голос
/ 31 марта 2020
df[] <- lapply(df, function(col) {
  # Split each value character by character
  NAs <- sapply(strsplit(as.character(col), split = ""), function(chars) {
    # Convert them back to integer to compare with `diff`
    # and verify the increment is always 1 or -1
    diff <- diff(as.integer(chars))
    !all(diff == 1) && !all(diff == -1)
  })
  # If not, replace those values with NA
  col[NAs] <- NA
  col
})
#> Warning in diff(as.integer(chars)): NAs introduced by coercion

#> Warning in diff(as.integer(chars)): NAs introduced by coercion

#> ...

#> Warning in diff(as.integer(chars)): NAs introduced by coercion
df
#>    id  A  B  C  D
#> 1   a  1  5  2  6
#> 2   a  2  6  3  5
#> 3   a NA NA  5 89
#> 4   a 67  9 NA  3
#> 5   a  8  8 NA  2
#> 6   b  9  1  2  9
#> 7   b  0 NA  7 NA
#> 8   b  6  9  6 12
#> 9   b  7  7  4 NA
#> 10  b  9  4  6  8

Создано в 2020-03-31 пакетом представ (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...