Eu tenho um dataframe:
mydf <- data.frame(
col1 = c("54", "abc", "123", "54 abc", "zzz", "a", "99"),
col2 = c("100", "200", "300", "400", "500", "600", "700"),
stringsAsFactors = FALSE
)
Neste dataframe, quero substituir todos os elementos por NA, a menos que atendam a uma destas condições:
- estritamente um número (por exemplo, "54" manter, "54 abc" descartar)
- pertencem a target_string
Eu não tinha certeza de como fazer isso em R usando apply, então tentei escrever um loop:
target_string <- c("a", "zzz")
replace_with_na_old <- function(df, target_string) {
for (i in 1:nrow(df)) {
for (j in 1:ncol(df)) {
value <- df[i, j]
if (!grepl("^[0-9]+$", value) && !(value %in% target_string)) {
df[i, j] <- NA
}
}
}
return(df)
}
mydf_cleaned_old <- replace_with_na_old(mydf, target_string)
Existe outra maneira de fazer isso?
Nota: Veja como substituir %in% por %like%:
replace_with_na_new <- function(df, target_string) {
for (i in 1:nrow(df)) {
for (j in 1:ncol(df)) {
value <- df[i, j]
if (!grepl("^[0-9]+$", value) && !any(sapply(target_string, function(pattern) grepl(pattern, value)))) {
df[i, j] <- NA
}
}
}
return(df)
}
Você já tem a lógica necessária para verificar isso, basta vetorizar.
Agora você pode aplicar esta função para cada coluna usando qualquer uma das
apply*
funções na base R.Ou se preferir
dplyr
podemos usaracross
para resultado semelhante.Você pode substituir todos os elementos que não pertencem a
target_string
e que contêm caracteres que não são dígitos.Você pode gerar o padrão regex antecipadamente e depois aplicar
grepl
, por exemplo,o que dá