I'm getting funny results using mutate
with a $
extraction when there happens to be a variable in the global environment with the same name as the element being extracted. (I'm running R 3.1.3 and dplyr 0.4.3.9.) This works fine:
library(dplyr)
df <- data.frame(time = 1:5, val = c(2.3, 3.9, NA, 8.1, 9.6))
mutate(df, val = approx(time, val, time)$y)
# time val
# 1 1 2.3
# 2 2 3.9
# 3 3 6.0
# 4 4 8.1
# 5 5 9.6
But if I define a global variable y
, funny things happen:
y <- 1L
mutate(df, val = approx(time, val, time)$y)
# Error: invalid subscript type 'integer'
Note that using double brackets with a string argument still works as expected:
mutate(df, val = approx(time, val, time)[['y']])
# time val
# 1 1 2.3
# 2 2 3.9
# 3 3 6.0
# 4 4 8.1
# 5 5 9.6
Interestingly, we get a different type of error if y
is a character:
y <- 'a'
mutate(df, val = approx(time, val, time)$y)
# Error: unsupported type for column 'val' (NILSXP, classes = NULL)
Finally, for completeness, here's an example that demonstrates that this is definitely not the usual behavior for list extraction:
l <- list(y = 1:4)
y <- 'a'
l$y
# [1] 1 2 3 4
Does anyone know why we get this weird behavior inside mutate
? And is there an easy way to fix this problem, aside from using double brackets for extraction or ensuring that there are no conflicting variables on the search path?
By the way, it looks like the OP in the following post might have had the same problem but didn't quite realize it: dplyr mutate fails with named vector?
As @clbieganek pointed out, this is a bug. It is not yet fixed (as of dplyr version 4.3)
Possible fix as suggested in comments:
$'y'
This is the issue that tracks this general problem: https://github.com/hadley/dplyr/issues/1400
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With