Some issues:
You cannot use if in a mutate like this: I'm inferring that your data is more than one row, in which case Visits == "NA" will be a logical vector, length greater than 1. The if conditional must have length-1. What you likely need is a vectorized conditional such as ifelse or replace.
There are a few things to realize: vectorized conditionals do not short-circuit (&& and || do short-circuit, & and | do not, and you cannot just interchange them); and ifelse has issues with classes other than logical, integer, numeric, and character.
Your use of replace is incorrect: it requires three arguments, it infers nothing. You cannot use just replace(0) hoping that it will know to look for a conditional outside of its call.
There is a big difference between the R symbol NA (which can be numeric, logical, string, etc) and the string "NA". There are times when mis-read data gives you strings of "NA", but typically it's not. Note that NA == . anything is going to be NA (not true/false), since NA can be interpreted as "can be anything" as well as "not applicable". Because of this, if you have NAs in your code, then . == "NA" is going to first internally coerce the data to strings, which does not convert NA to "NA", and then look for the literal "NA", not what you want/need. I hope that makes sense.
The error message suggests that you are not passing in data. mutate(Visited = ...) works fine if the call to mutate is in a dplyr/magrittr "pipe" (%>%), but by itself mutate requires its first argument to be a data.frame, as in mutate(mydata, Visited=...).
Here are some equivalent alternatives that should work for you:
mydata %>%
mutate(
Visited1 = ifelse(!is.na(Visits) & Visits > 0, 1, 0),
Visited2 = replace(rep(1, n()), is.na(Visits) | Visits <= 0, 0),
Visited3 = +(!is.na(Visits) & Visits > 0)
)
The third takes advantage of R's coercion from logical to integer with the +(.) shortcut.
You pick which you prefer.