En R tengo:

library(tidyverse)
full_names <- tibble(FIRM = c("APPLE INC.", "MICROSOFT CORPORATION", "GOOGLE", "TESLA INC.", "ABBOTT LABORATORIES"), 
                 TICKER = c("AAPL", "MSFT", "GOOGL", "TSLA", "ABT"),
                 ID = c(111, 222, 333, 444, 555)) # a dataset with full names of firms, including some IDs
abbr_names <- c("Abbott", "Apple", "Coca-Cola", "Pepsi, "Microsoft", "Tesla") # a vector with abbreviated names of firms

Quiero verificar si los nombres abreviados están en el conjunto de datos de nombres completos, y si es verdadero, coinciden posteriormente con la fila full_names con el vector abbr_names, como:

    [1]        [2]                    [3]   [4]
[1] Abbott     ABBOTT LABORATORIES    ABT   555
[2] Apple      APPLE INC.             AAPL  111
[3] Microsoft  MICROSOFT CORPORATION  MSFT  222
[4] Tesla      TESLA INC.             TSLA  444

Intenté varias funciones str_extract y grepl, pero no pude hacerlo funcionar todavía.

0
Oscar 5 mar. 2018 a las 15:14

4 respuestas

La mejor respuesta
matches <- unlist(sapply(toupper(abbr_names), grep, x = full_names$FIRM, value = TRUE))

Eso le dará un vector con los nombres como abreviaturas y las empresas como valores

names(matches)
# [1] "ABBOTT"    "APPLE"     "MICROSOFT" "TESLA"  
c(firm_matches, use.names = FALSE)
# [1] "ABBOTT LABORATORIES"   "APPLE INC."            "MICROSOFT CORPORATION" "TESLA INC."  

Hay una variedad de formas de armar esto ... enredado ...


Del comentario de @Oscar, obtenemos el resultado deseado con un total de dos líneas de código:

matches <- unlist(sapply(toupper(abbr_names), grep, x = full_names$FIRM, value = TRUE))
tibble(ABBR_FIRM = names(matches), FIRM = matches) %>% left_join(., full_names, by = "FIRM")
3
De Novo 5 mar. 2018 a las 13:00

¿Qué tal esto?

full_names$row_num <- 1:nrow(full_names)

do.call(rbind, 
        lapply(abbr_names, 
               function(x){
                 if(sum(grepl(x, full_names$FIRM, ignore.case = TRUE)) > 0){
                   row <- grepl(x, full_names$FIRM, ignore.case = TRUE) %>% 
                     which()} else {row <- 0}
                 data.frame("name" = x,
                            "row_num" = row)})) %>% 
  right_join(full_names, by = "row_num")
1
DS_UNI 5 mar. 2018 a las 12:39

Otra opción podría ser, por ejemplo, esto ...

map_int(abbr_names, ~ {
  idx <- grep(., full_names$FIRM, ignore.case = TRUE)
  if (length(idx) == 0) return(NA) else return(idx)
}) %>% 
  cbind(ABBR = abbr_names, FIRM = full_names$FIRM[.]) %>% 
  as.tibble() %>% 
  left_join(full_names, by = "FIRM") %>%
  complete(FIRM)

# A tibble: 4 x 5
  FIRM                  .     ABBR      TICKER    ID
  <chr>                 <chr> <chr>     <chr>  <dbl>
1 ABBOTT LABORATORIES   5     Abbott    ABT      555
2 APPLE INC.            1     Apple     AAPL     111
3 MICROSOFT CORPORATION 2     Microsoft MSFT     222
4 TESLA INC.            4     Tesla     TSLA     444

Solo quería publicarlo :)

0
erocoar 5 mar. 2018 a las 13:14

Mi consejo, active todas las palabras en mayúsculas o minúsculas. Es más fácil para las funciones ya que grepl hace la comparación.

Mi código:

library(tidyverse)

full_names <- tibble(FIRM = c("APPLE INC.", "MICROSOFT CORPORATION", "GOOGLE", "TESLA INC.", "ABBOTT LABORATORIES"), 
                     TICKER = c("AAPL", "MSFT", "GOOGL", "TSLA", "ABT"),
                     ID = c(111, 222, 333, 444, 555)) # a dataset with full names of firms, including some IDs

abbr_names <- c("Abbott", "Apple", "Coca-Cola", "Microsoft", "Tesla") # a vector with abbreviated names of firms

Aquí creé una nueva columna, la que queremos indexar los retornos de grepl

full_names$new_column <- NA

Luego, hice un bucle en el nombre que queremos indexar en el marco de datos

for(i in 1:length(abbr_names)){
  search_test <- grepl(tolower(substr(abbr_names[i], 0,4)), tolower(full_names$FIRM))
  position <- grep("TRUE", search_test)
  full_names$new_column[position] <- abbr_names[i]
}

El resultado es el siguiente marco de datos:

   FIRM               TICKER    ID  new_column
1 APPLE INC.            AAPL     111 Apple     
2 MICROSOFT CORPORATION MSFT     222 Microsoft 
3 GOOGLE                GOOGL    333 NA        
4 TESLA INC.            TSLA     444 Tesla     
5 ABBOTT LABORATORIES   ABT      555 Abbott

"GOOG" no está en el vector abbr_names, por lo que el retorno es NA

0
Arduin 5 mar. 2018 a las 12:54