Измените NA на часть строки в другом столбце - PullRequest
0 голосов
/ 03 января 2019

Я хочу извлечь некоторые строки из определенного столбца и заменить NA. Для data.frame, приведенного ниже, я хочу извлечь строку в другом столбце, если в сообщении электронной почты указано NA. Строка всегда находится между «developer_id =» и «& app_id» в столбце «Тема».

    |Email      |  Subject                                    |
    |a@site.com |  developer_id=a@site.com&app_id=a&appname=a |
    |NA         |  developer_id=b@site.com&app_id=b&appname=b |
    |c@site.com |  NA                                         |
    |NA         |  developer_id=d@site.com&app_id=d&appname=d |

Ожидаемые результаты следующие.

    |Email      |  Subject                                    |
    |a@site.com |  developer_id=a@site.com&app_id=a&appname=a |
    |b@site.com |  developer_id=b@site.com&app_id=b&appname=b |
    |c@site.com |  NA                                         |
    |d@site.com |  developer_id=d@site.com&app_id=d&appname=d |

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Как ваш запрос,

  1. Когда Subject == NA, Email = Email
  2. Когда Subject != NA, извлечение строка
    • междуdeveloper_id=
    • и &app_id

Это извлечение может быть выполнено функцией stringr::str_extract(x, pattern)

с использованием регулярного выражения pattern = "(?<=developer_id=).*(?=&app_id)".

В первой части (?<=developer_id=) будут найдены символы , за которыми следует developer_id=..* означает любой символ после этого шаблона.После этого (?=&app_id) будет соответствовать символам, за которыми следует &app_id.

Другими словами, мы можем найти нужную часть между developer_id= и &app_id.

Используя dplyr::mutate и ifelse(), вы можете легко преобразовать данный столбец.

library(tidyverse) # dplyr, stringr
mydf %>% # your data
  mutate(Email = ifelse(
    is.na(Subject),
    Email,
    str_extract(Subject, pattern = "(?<=developer_id=).*(?=&app_id)")
  ))
#> # A tibble: 4 x 2
#>   Email      Subject                                   
#>   <chr>      <chr>                                     
#> 1 a@site.com developer_id=a@site.com&app_id=a&appname=a
#> 2 b@site.com developer_id=b@site.com&app_id=b&appname=b
#> 3 c@site.com <NA>                                      
#> 4 d@site.com developer_id=d@site.com&app_id=d&appname=d
0 голосов
/ 03 января 2019

Один вариант с base R будет состоять в том, чтобы извлечь подстроку второго столбца, которая соответствует элементам NA в первом столбце, и обновить элементы первого столбца NA, извлекая значение

i1 <- is.na(df1$Email) # create a logical index
df1$Email[i1] <- regmatches(df1$Subject[i1], 
                   regexpr("[a-z]+@.*\\.com", df1$Subject[i1]))
df1
#       Email                                    Subject
#1 a@site.com developer_id=a@site.com&app_id=a&appname=a
#2 b@site.com developer_id=b@site.com&app_id=b&appname=b
#3 c@site.com                                       <NA>
#4 d@site.com developer_id=d@site.com&app_id=d&appname=d

Или с использованием tidyverse

library(tidyverse)
df1 %>%
  mutate(Email = case_when(is.na(Email) ~ str_extract(Subject, "[a-z]+@.*\\.com"), 
                  TRUE ~ Email))

Кроме того, поскольку OP упоминает об отдельных строках в качестве идентификаторов, мы можем использовать регулярное выражение для просмотра вдоль этих строк, т.е. для извлечения всех символов, следующих за developer_id=и предшествует &app_id

df1 %>%
   mutate(Email = case_when(is.na(Email) ~ 
         str_extract(Subject, "(?<=developer_id\\=).*(?=&app_id)"), 
        TRUE ~ Email))

data

df1 <- structure(list(Email = c("a@site.com", NA, "c@site.com", NA), 
Subject = c("developer_id=a@site.com&app_id=a&appname=a", 
"developer_id=b@site.com&app_id=b&appname=b", NA, 
  "developer_id=d@site.com&app_id=d&appname=d"
)), class = "data.frame", row.names = c(NA, -4L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...