замена значений NA с помощью stringr - PullRequest
2 голосов
/ 24 октября 2019

Мои данные выглядят следующим образом:

   var1 var2 var3
1    9V  .6V  77V
2    6V  .3V  15V
3    9V  .7V 114V
4   12V 1.0V 199V
5   14V 1.2V 245V
6   13V  .8V 158V
7   11V  .6V 136V
8   11V  .7V 132V
9   12V  .8V 171V
10  11V  .7V 155V
11  13V  .8V 166V
12  11V  .7V 138V
13  11V  .9V 173V
14   9V  .8V 143V
15   8V  .7V 105V
16   4V  .4V  21V
17   8V  .4V  26V
18  10V  .8V 154V
19   9V  .8V 130V
20  10V  .7V 113V
21  10V  .6V 102V
22  11V  .8V 135V
23   9V  .7V 120V
24  10V  .7V 126V
25   7N  .6N 124N
26  14N 1.1N 210N

Последние 2 строки содержат N. Я пытаюсь установить для NA эти наблюдения, которые содержат N.

Я пробую некоторую комбинацию str_detect и str_replace, но не могу заставить ее работать.

ДополнительноУ меня есть другие (очень редко) буквы, например M и P - я хотел бы найти способ установить, если в наблюдениях содержится одна из этих букв, а затем установить это наблюдение на NA,т.е. c(var1:var3) %in% str_detect(c("N", "M", "P")) ... str_replace_all.

Данные:

    structure(list(var1 = c("9V", "6V", "9V", "12V", "14V", "13V", 
"11V", "11V", "12V", "11V", "13V", "11V", "11V", "9V", "8V", 
"4V", "8V", "10V", "9V", "10V", "10V", "11V", "9V", "10V", "7N", 
"14N", "7V", "5V", "7V", "9V", "8V", "8V", "5V", "4V", "4V", 
"5V", "7V", "5V", "6V", "8V", "9V", "6V", "6V", "7V", "8V", "7V", 
"8V", "8V", "7V", "8V"), var2 = c(".6V", ".3V", ".7V", "1.0V", 
"1.2V", ".8V", ".6V", ".7V", ".8V", ".7V", ".8V", ".7V", ".9V", 
".8V", ".7V", ".4V", ".4V", ".8V", ".8V", ".7V", ".6V", ".8V", 
".7V", ".7V", ".6N", "1.1N", ".4V", ".3V", ".4V", ".6V", ".5V", 
".6V", ".4V", ".3V", ".2V", ".3V", ".4V", ".3V", ".3V", ".5V", 
".6V", ".4V", ".4V", ".4V", ".5V", ".4V", ".4V", ".5V", ".4V", 
".4V"), var3 = c("77V", "15V", "114V", "199V", "245V", "158V", 
"136V", "132V", "171V", "155V", "166V", "138V", "173V", "143V", 
"105V", "21V", "26V", "154V", "130V", "113V", "102V", "135V", 
"120V", "126V", "124N", "210N", "35V", "9V", "48V", "91V", "81V", 
"80V", "14V", "11V", "7V", "13V", "34V", "18V", "15V", "58V", 
"76V", "29V", "30V", "31V", "32V", "34V", "57V", "58V", "52V", 
"49V")), row.names = c(NA, 50L), class = "data.frame")

Ответы [ 3 ]

2 голосов
/ 24 октября 2019

Вот одно из решений:

x[] <- lapply(x, function(s) ifelse(grepl("N$", s), NA_character_, s))
x
#    var1 var2 var3
# 1    9V  .6V  77V
# 2    6V  .3V  15V
# 3    9V  .7V 114V
# 4   12V 1.0V 199V
# 5   14V 1.2V 245V
# 6   13V  .8V 158V
# 7   11V  .6V 136V
# 8   11V  .7V 132V
# 9   12V  .8V 171V
# 10  11V  .7V 155V
# 11  13V  .8V 166V
# 12  11V  .7V 138V
# 13  11V  .9V 173V
# 14   9V  .8V 143V
# 15   8V  .7V 105V
# 16   4V  .4V  21V
# 17   8V  .4V  26V
# 18  10V  .8V 154V
# 19   9V  .8V 130V
# 20  10V  .7V 113V
# 21  10V  .6V 102V
# 22  11V  .8V 135V
# 23   9V  .7V 120V
# 24  10V  .7V 126V
# 25 <NA> <NA> <NA>
# 26 <NA> <NA> <NA>
# 27   7V  .4V  35V
# 28   5V  .3V   9V
# 29   7V  .4V  48V
# 30   9V  .6V  91V
# 31   8V  .5V  81V
# 32   8V  .6V  80V
# 33   5V  .4V  14V
# 34   4V  .3V  11V
# 35   4V  .2V   7V
# 36   5V  .3V  13V
# 37   7V  .4V  34V
# 38   5V  .3V  18V
# 39   6V  .3V  15V
# 40   8V  .5V  58V
# 41   9V  .6V  76V
# 42   6V  .4V  29V
# 43   6V  .4V  30V
# 44   7V  .4V  31V
# 45   8V  .5V  32V
# 46   7V  .4V  34V
# 47   8V  .4V  57V
# 48   8V  .5V  58V
# 49   7V  .4V  52V
# 50   8V  .4V  49V

Если в ваших данных есть столбцы, в которых вы не хотите выполнять эту замену, просто используйте подмножество:

x[2:3] <- lapply(x[2:3], ...)

Вариант:

library(dplyr)
x %>%
  mutate_at(vars(var1, var2, var3), ~ if_else(grepl("N$", .), NA_character_, .))
# or, if all columns
x %>%
  mutate_all(~ if_else(grepl("N$", .), NA_character_, .))

Использование NA_character_ имеет два аспекта:

  1. В базовой версии R это просто декларативное выражение, говорящее, что я намерен, чтобы результат всегдаbe character;
  2. В версии dplyr ее функция between требует, чтобы класс аргументов "yes" и "no" был одинаковым, а class(NA) не class("A").
1 голос
/ 25 октября 2019

Решение dplyr - stringr, которое вы пытаетесь выяснить, будет выглядеть следующим образом:

library(stringr)
library(dplyr)

df1 %>% 
  mutate_at(vars(var1:var3), 
            list(~str_replace_all(., "N$|M$|P$", replacement = NA_character_)))

#>    var1 var2 var3
#> 1    9V  .6V  77V
#> 2    6V  .3V  15V
#> 3    9V  .7V 114V
#> 4   12V 1.0V 199V
#> 5   14V 1.2V 245V
## ...
#> 20  10V  .7V 113V
#> 21  10V  .6V 102V
#> 22  11V  .8V 135V
#> 23   9V  .7V 120V
#> 24  10V  .7V 126V
#> 25 <NA> <NA> <NA>
#> 26 <NA> <NA> <NA>
#> 27   7V  .4V  35V
#> 28   5V  .3V   9V
#> 29   7V  .4V  48V
#> 30   9V  .6V  91V
## ...
#> 45   8V  .5V  32V
#> 46   7V  .4V  34V
#> 47   8V  .4V  57V
#> 48   8V  .5V  58V
#> 49   7V  .4V  52V
#> 50   8V  .4V  49V
1 голос
/ 25 октября 2019

Вам просто нужно изменить свой шаблон на «N | M | P»:

dat <- structure(list(var1 = c("9V", "6V", "9V", "12V", "14V", "13V", 
                        "11V", "11V", "12V", "11V", "13V", "11V", "11V", "9V", "8V", 
                        "4V", "8V", "10V", "9V", "10V", "10V", "11V", "9V", "10V", "7N", 
                        "14N", "7V", "5V", "7V", "9V", "8V", "8V", "5V", "4V", "4V", 
                        "5V", "7V", "5V", "6V", "8V", "9V", "6V", "6V", "7V", "8V", "7V", 
                        "8V", "8V", "7V", "8V"), var2 = c(".6V", ".3V", ".7V", "1.0V", 
                                                          "1.2V", ".8V", ".6V", ".7V", ".8V", ".7V", ".8V", ".7V", ".9V", 
                                                          ".8V", ".7V", ".4V", ".4V", ".8V", ".8V", ".7V", ".6V", ".8V", 
                                                          ".7V", ".7V", ".6N", "1.1N", ".4V", ".3V", ".4V", ".6V", ".5V", 
                                                          ".6V", ".4V", ".3V", ".2V", ".3V", ".4V", ".3V", ".3V", ".5V", 
                                                          ".6V", ".4V", ".4V", ".4V", ".5V", ".4V", ".4V", ".5V", ".4V", 
                                                          ".4V"), var3 = c("77V", "15V", "114V", "199V", "245V", "158V", 
                                                                           "136V", "132V", "171V", "155V", "166V", "138V", "173V", "143V", 
                                                                           "105V", "21V", "26V", "154V", "130V", "113V", "102V", "135V", 
                                                                           "120V", "126V", "124N", "210N", "35V", "9V", "48V", "91V", "81V", 
                                                                           "80V", "14V", "11V", "7V", "13V", "34V", "18V", "15V", "58V", 
                                                                           "76V", "29V", "30V", "31V", "32V", "34V", "57V", "58V", "52V", 
                                                                           "49V")), row.names = c(NA, 50L), class = "data.frame")


library(stringr)
library(dplyr)
dat %>% mutate(var3 = str_replace_all(var3, c("N|M|P"), replacement = NA_character_))
...