Вложенный l oop не приносит желаемого результата - PullRequest
0 голосов
/ 02 марта 2020

Я довольно новичок в r, так что это может быть глупым сомнением.

У меня есть фрейм данных, в котором я хочу циклически перебирать строки в указанном столбце c и проверять, есть ли имя в нем находится в другой переменной. Хотя значение в каждой строке может иметь несколько имен, разделенных точками с запятой. Мне нужно проверить каждое из них. Я пробовал вложенный l oop, но я получаю список повторяющихся значений. Мой код описан ниже:

# Column in df I want to modify:
company.tickers  
----------
CARD3  
CSAN3  
CVCB3  
ELET3;ELET5;ELET6  
ENBR3  
FESA3;FESA4  
OIBR3;OIBR4  
PETR3;PETR4  
PTBL3  
TUPY3  
VLID3  

# stock names I would like to keep
stocks <- c("CARD3", "TUPY3", "OIBR3", "FESA4", "PTBL3", "VLID3","CNTO3","CSAN3","ELET3","PETR4","ENBR3")

result=list()

# Cycle through rows
for (i in 1:length(df.statements$company.tickers)){

  print(df.statements$company.tickers[i])
  stock.tickers <- strsplit(row,";")

  # Cycle through names in a cell
  for (j in 1:length(stock.tickers)) {

    if (stock.tickers[j] %in% stocks){

      print(stock.tickers[j])

      result <- c( result, stock.tickers[j])

    }

  }

}

# My expected result is the following column:
company.tickers 
----------
CARD3  
CSAN3  
CVCB3  
ELET3
ENBR3  
FESA4  
OIBR3
PETR4  
PTBL3  
TUPY3  
VLID3 

Ответы [ 3 ]

1 голос
/ 05 марта 2020

Вот попытка использования tidyr::separate для временного разделения столбца тикеров на отдельные столбцы. Удлините / приведите в порядок данные и затем отфильтруйте их, чтобы получить то, что вы хотите.

Буду благодарен за комментарии, которые помогут улучшить эту технику.

suppressPackageStartupMessages(library(dplyr))
suppressPackageStartupMessages(library(tidyr))
suppressPackageStartupMessages(library(purrr))

company.tickers = c(
  "CARD3",
  "CSAN3",
  "CVCB3",
  "ELET3;ELET5;ELET6",
  "ENBR3",
  "FESA3;FESA4",
  "OIBR3;OIBR4",
  "PETR3;PETR4",
  "PTBL3",
  "TUPY3",
  "VLID3")

random.data <- runif(length(company.tickers))
stocks <- c("CARD3", "TUPY3", "OIBR3", "FESA4", "PTBL3", "VLID3", "CNTO3", "CSAN3", "ELET3", "PETR4", "ENBR3")

# construct a data frame
df <- dplyr::tibble(company.tickers, random.data)

# work out how many columns `separate` will need, and create a vector of unusual column names
# it feels weird that we need to do this
# but without this I always get an error from `separate` in the next step

new_cols <- paste0("zqzcol", 1:max(map_int(strsplit(df$company.tickers, ";"), length)))

# temporarily create new columns using `separate`
# then use `pivot_longer` to reabsorb these into long, tidy data
# then filter this by what is in `stocks`
# then tidy up using `select` (optional)

df %>% 
  tidyr::separate(col = company.tickers, sep = ";", into = new_cols) %>% 
  pivot_longer(cols = starts_with("zqzcol"), values_to = "company.tickers", values_drop_na = TRUE) %>% 
  filter(company.tickers %in% stocks) %>% 
  select(company.tickers, everything(), -name)
#> Warning: Expected 3 pieces. Missing pieces filled with `NA` in 10 rows [1, 2, 3,
#> 5, 6, 7, 8, 9, 10, 11].
#> # A tibble: 10 x 2
#>    company.tickers random.data
#>    <chr>                 <dbl>
#>  1 CARD3                0.568 
#>  2 CSAN3                0.0370
#>  3 ELET3                0.119 
#>  4 ENBR3                0.276 
#>  5 FESA4                0.196 
#>  6 OIBR3                0.301 
#>  7 PETR4                0.504 
#>  8 PTBL3                0.712 
#>  9 TUPY3                0.790 
#> 10 VLID3                0.956

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

1 голос
/ 02 марта 2020

Что-то вроде этого возможно?

#build regex
stocks.regex <- paste0( stocks, collapse = "|")
#subset using grepl ans the new regex
subset( df, grepl( stocks.regex, df$company.tickers ) )

пример данных

library(data.table)
df <- setDF(fread("company.tickers  
CARD3  
CSAN3  
CVCB3  
ELET3;ELET5;ELET6  
ENBR3  
FESA3;FESA4  
OIBR3;OIBR4  
PETR3;PETR4  
PTBL3  
TUPY3  
VLID3", sep = ","))

stocks <- c("CARD3", "TUPY3", "OIBR3", "FESA4", "PTBL3", "VLID3","CNTO3","CSAN3","ELET3","PETR4","ENBR3")
0 голосов
/ 03 марта 2020

A tidyverse альтернатива очень умному ответу Вымпела:

suppressPackageStartupMessages(library(dplyr))

company.tickers = c(
"CARD3",
"CSAN3",
"CVCB3",
"ELET3;ELET5;ELET6",
"ENBR3",
"FESA3;FESA4",
"OIBR3;OIBR4",
"PETR3;PETR4",
"PTBL3",
"TUPY3",
"VLID3")

stocks <- c("CARD3", "TUPY3", "OIBR3", "FESA4", "PTBL3", "VLID3", "CNTO3", "CSAN3", "ELET3", "PETR4", "ENBR3")

df <- dplyr::tibble(company.tickers)

filter_df <- function(x, df, col) {
  df %>% 
    dplyr::filter(stringr::str_detect(.data[[col]], x))
}

purrr::map_dfr(stocks, ~ filter_df(., df = df, col = "company.tickers")) %>% 
  dplyr::distinct()
#> # A tibble: 10 x 1
#>    company.tickers  
#>    <chr>            
#>  1 CARD3            
#>  2 TUPY3            
#>  3 OIBR3;OIBR4      
#>  4 FESA3;FESA4      
#>  5 PTBL3            
#>  6 VLID3            
#>  7 CSAN3            
#>  8 ELET3;ELET5;ELET6
#>  9 PETR3;PETR4      
#> 10 ENBR3

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

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