Eu tenho o seguinte problema
library(tidyverse)
test <- tibble(A = c("1994:2020, 2021"), B = 1995)
Gostaria de verificar se o ano em B está nos anos indicados na coluna A. Os anos na coluna A são uma string (os dados são lidos de um arquivo Excel). O seguinte claramente não funciona (dá "Não", mas eu gostaria de ter "Sim"):
test %>%
mutate(InA = ifelse(B %in% A, "Yes", "No"))
> test
# A tibble: 1 x 2
A B
<chr> <dbl>
1 1994:2020, 2021 1995
Presumo que devo separar a string em A. No entanto, A pode conter mais de um intervalo e/ou mais de um ano (por exemplo, ("1994:2012, 2014, 2016:2020, 2021") e usando "separar" para estruturas diferentes fica complicado.Talvez haja uma maneira mais direta.
Vamos criar mais alguns exemplos:
Se você confiar em sua opinião, poderá avaliá-la.
Solução Base R
É assim que eu faria.
tidyverse
soluçãoAo carregar
library(tidverse)
sua pergunta, você também pode fazer:Observe que ambas as abordagens também funcionarão se
A
contiverem intervalos não contíguos, por exemplo1994:2012, 2014
, o que nem todas as respostas funcionarão.Isenção de responsabilidade obrigatória
Com qualquer abordagem, vale a pena ler Avaliar a expressão dada como uma string e Quais são especificamente os perigos de eval(parse(...))? . Não use esta abordagem se você não controlar os dados de entrada. Imagine um quadro de dados de entrada contendo strings como esta.
Ambas as abordagens executarão o código e imprimirão o aviso. Portanto, se esta for uma possibilidade, use uma abordagem diferente.
Ideia
Se você só precisa saber se um ponto cai em um intervalo , você só precisa saber as relações entre o ponto e ambas as arestas desse intervalo.
Matematicamente, dado um ponto
p
e um intervalo[lb, ub]
,p
está dentro do intervalo (incluindo as arestas) se e somente se(p-lb)*(p-ub) <= 0
, e assim você pode tentarprod(p - c(lb,ub))
verificar apenas seu sinal.Código
Você pode tentar o código abaixo (também obrigado pelos dados fornecidos por @Roland )
que dá
Isso não será rápido para grandes dados, mas funciona:
Primeiro dividimos os caracteres em intervalos individuais e depois dividimos esses intervalos para obter seus limites. Comparar com limites é fácil, assim como comparar com um único ano (em vez de um intervalo).
Esta é outra opção de como fazer:
Equivalente do Tidyverse à estratégia de @SamR
Criado em 08/03/2024 com reprex v2.0.2