Reputation: 1038
Is it possible to reference other var in transform
?
For instance:
Data = transform(Data,
m = x,
d = m,
c = m * 2
)
Upvotes: 1
Views: 55
Reputation: 269556
Here are some solutions. For reproducibility we will assume this definition for Data
:
Data <- data.frame(x = 1)
1) iterated transform Try an iterated transform:
transform(transform(Data, m = x), d = m, c = m*2)
2) within or use within
:
within(Data, { m <- x; d <- m; c <- m*2 })
3) my.transform There is also an alternate transform defined here that supports such behavior.
my.transform(Data, m = x, d = m, c = m*2)
Note that this is the only answer here that supports setting the variables out of order, e.g.
my.transform(Data, d = m, c = m*2, m = x)
4) dplyr::mutate mutate
in the dplyr package also supports this:
library(dplyr)
mutate(Data, m = x, d = m, c = m*2)
Upvotes: 5
Reputation: 174813
No, if you mean a variable you create in the current transform()
call:
df <- data.frame(x = 1:10)
df2 <- transform(df, m = x, d = m, c = m * 2)
> df <- data.frame(x = 1:10)
> df2 <- transform(df, m = x, d = m, c = m * 2)
Error in eval(expr, envir, enclos) : object 'm' not found
The obvious solution is to do two transform()
calls:
df2 <- transform(df, m = x)
df2 <- transform(df2, d = m, c = m * 2)
head(df2)
> head(df2)
x m d c
1 1 1 1 2
2 2 2 2 4
3 3 3 3 6
4 4 4 4 8
5 5 5 5 10
6 6 6 6 12
or nest them
df3 <- transform(transform(df, m = x), d = m, c = m * 2)
> head(df3)
x m d c
1 1 1 1 2
2 2 2 2 4
3 3 3 3 6
4 4 4 4 8
5 5 5 5 10
6 6 6 6 12
The alternative is within()
, which can do what you want but is slightly less user-friendly:
df4 <- within(df, {
m <- x
d <- m
c <- m * 2
})
> head(df4)
x c d m
1 1 2 1 1
2 2 4 2 2
3 3 6 3 3
4 4 8 4 4
5 5 10 5 5
6 6 12 6 6
One idiosyncrasy of this is that you don't have any control of the ordering of the new variables.
Note that within()
works because the entire expression (the thing in { ... }
) is evaluated within an environment containing the variables in df
. Hence m
is available in that environment as it is created in the first line of the expression.
Upvotes: 1