If I understand right, you're looking for values that are the same as their 2 adjacent values on either side, and in this case you're happy to ignore the 'missing' adjacent values for the 2 first & 2 last values.
Using base R:
sameasadj=function(v,n=2,include_ends=T) {
if(include_ends){vv=c(rep(head(v,1),n),v,rep(tail(v,1),n))}
else {vv=c(rep(NA,n),v,rep(NA,n))}
sapply(seq_along(v),function(i) diff(range(vv[i:(i+2*n)]))==0)
}
df$comp = sameasadj(df$a)
df$comp
Output:
[1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
Explanation:
sameasadj=function(v,n=2,include_ends=T) = define function sameasadj to test whether each value is the same as its adjacent neighbours on each side. We can give the option to choose the number n of adjacent neighbours (in your case 2), and whether-or-not to include the ends (or to return 'NA' for these, since they lack enough neighbours on one side).
if(include_ends){vv=c(rep(head(v,1),n),v,rep(tail(v,1),n))} = if we want to include the ends, then we just add the 'missing' neighbours so that they match
else {vv=c(rep(NA,n),v,rep(NA,n))} = otherwise we add 'NA' values
sapply(seq_along(v),function(i) = go along each position i in the vector...
diff(range(vv[i:(i+2*n)]))==0) = ...and check whether the elements from i to i+2*n are all the same (diff(range(x))==0 will return TRUE if all elements of x are the same)
Putting it all into a function makes it easy to change your mind later about the number of adjacent neighbours, or what to do with the ends...