Посчитайте вхождения символа и верните столбец с количеством, но только в определенных случаях в R - PullRequest
0 голосов
/ 13 января 2020

У меня есть данные, которые выглядят так:

 structure(list(Age = c("25", "22", "54", "62", "86", "25", "44", 
 "54", "48", "50"), full_name = c("DOE, MARTIN", "SMITH, RYAN E", 
 "JOHN, KENNETH", "DOE, LAWRENCE A", "FU, EDGAR", "ALEXANDER, AL", 
 "BARR, DONALD", "STEVENS, RICHARD", "LUIGI, MARIO", "SMITH, GLEN"
 ), ems_interventions = c("Oxygen - Prehospital Cervical Collar - Prehospital Long Spine Board - 
 Prehospital IV Access - Prehospital", 
 NA, "*ND", "*ND", "IV Access - Prehospital Cervical Collar - Prehospital Long Spine Board - 
  Prehospital", 
 "*ND", "Cervical Collar - Prehospital Long Spine Board - Prehospital IV Access - Prehospital", 
 "*ND", "Endotrach Tube (ETT)", "*ND")), class = c("grouped_df", 
 "tbl_df", "tbl", "data.frame"), row.names = c(NA, -10L), groups = structure(list(
full_name = c("ABREU, MARTIN", "ADAMS, RYAN E", "ADLER, KENNETH", 
"AGLI, LAWRENCE A", "ALBERT, EDGAR", "ALEXANDER, AL", "ALEXANDER, DONALD", 
"ALEXANDER, RICHARD", "ALEXIS, MARIO", "ALLEN, GLEN"), Age = c("25", 
"22", "54", "62", "86", "25", "44", "54", "48", "50"), .rows = list(
    1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L)), row.names = c(NA, 
 -10L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE))

, и я хотел бы добавить новый столбец, который подсчитывает количество фрагментов слов между "-" в столбце ems_interventions. Т.е. для «Луиджи, Марио», у которого была только «эндотраховая трубка (ETT)», он получил бы «1» в этой новой колонке. За «Барра, Дональда», у которого были «шейный воротник - догоспитальная доска для длинного позвоночника - догоспитальный внутривенный доступ - догоспитальный», он получил 4 в новой колонке. et c ..

Уловка в том, что я хотел бы отфильтровать людей, которые имели NA или "* ND", и они получили бы ноль.

Спасибо за ваша помощь!

Ответы [ 4 ]

3 голосов
/ 13 января 2020

Если это просто "-", который вы используете для разделения строк, мы можем сначала strsplit соответствующий столбец, а затем подсчитать длину каждого элемента этого списка.

ungroup(dat) %>%
  mutate(
    counts = if_else(ems_interventions %in% c(NA, "*ND"), 0L,
                     lengths(strsplit(ems_interventions, "-")))
  ) %>%
  select(counts, everything())
# # A tibble: 10 x 4
#    counts Age   full_name      ems_interventions                                                
#     <int> <chr> <chr>          <chr>                                                            
#  1      5 25    DOE, MARTIN    "Oxygen - Prehospital Cervical Collar - Prehospital Long Spine B~
#  2      0 22    SMITH, RYAN E  <NA>                                                             
#  3      0 54    JOHN, KENNETH  *ND                                                              
#  4      0 62    DOE, LAWRENCE~ *ND                                                              
#  5      4 86    FU, EDGAR      "IV Access - Prehospital Cervical Collar - Prehospital Long Spin~
#  6      0 25    ALEXANDER, AL  *ND                                                              
#  7      4 44    BARR, DONALD   Cervical Collar - Prehospital Long Spine Board - Prehospital IV ~
#  8      0 54    STEVENS, RICH~ *ND                                                              
#  9      1 48    LUIGI, MARIO   Endotrach Tube (ETT)                                             
# 10      0 50    SMITH, GLEN    *ND                                                              

( Я переупорядочил столбцы только для того, чтобы сделать его более читабельным, сначала counts.

К вашему сведению: причина, по которой я пропустил базу R, заключалась в том, что предоставленный образец данных представляет собой tibble, предлагая предпочтение для tidyverse решения. Для простого решения base-R используйте ifelse вместо if_else и добавьте имена переменных с dat$. * Пожала плечами *)

0 голосов
/ 13 января 2020

Самое простое и базовое решение R это:

df$count <- ifelse(is.na(df$ems_interventions) | df$ems_interventions=="*ND", 0, 
                   lengths(strsplit(df$ems_interventions, "-")))
0 голосов
/ 13 января 2020

Вы также можете использовать stringr::str_count.

# "base-r" version
df["Count"] = lapply(df["ems_interventions"], function(p) ifelse(p %in% c(NA, "*ND"), 0L, stringr::str_count(p, "-") +1L))

# tidyverse version
df %>% mutate(count = ifelse(ems_interventions %in% c(NA, "*ND"), 0L, stringr::str_count(ems_interventions, "-") +1L))
0 голосов
/ 13 января 2020

Я бы предложил подход с tidyr::unnest (я пользуюсь тем фактом, что ваши данные уже сгруппированы):

library(tidyverse)    
# this just counts
data %>%
  mutate(
    ems_list = str_split(ems_interventions, " - "),
    ems_length = map_int(ems_list, length)
  )

# to filter some of elements - unnest them:
data %>%
  mutate(
    ems_list = str_split(ems_interventions, " - "),
    ems_length = map_int(ems_list, length)
  ) %>%
  unnest(cols = ems_list)

# then filter and count:
data %>%
  mutate(
    ems_list = str_split(ems_interventions, " - "),
    ems_length = map_int(ems_list, length)
  ) %>%
  unnest(cols = ems_list) %>%
  filter(!str_detect(ems_list, "ND")) %>%
  summarise(ems_without_nd = n())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...