I have a dataset like this:
data.frame(x = c(1:5), y = c(0:4), z = c(2:6))
x y z
1 1 0 2
2 2 1 3
3 3 2 4
4 4 3 5
5 5 4 6
I would like to get a dataset like this:
x y z y-x z-y
1 1 0 2 -1 2
2 2 1 3 -1 2
3 3 2 4 -1 2
4 4 3 5 -1 2
5 5 4 6 -1 2
when I use:
a <- a %>% mutate(across((x:z), ~. - lag(.)))
I get:
x y z
1 NA NA NA
2 1 1 1
3 1 1 1
4 1 1 1
5 1 1 1
That is, the mutate is subtracting in the same column and I needed to subtract in different columns. How can I resolve this?
CodePudding user response:
I wouldn't use dplyr
for this. I would use base R directly:
diff_cols = your_data[-1] - your_data[-ncol(your_data)]
names(diff_cols) = paste0(
names(your_data)[-1],
"-",
names(your_data)[-ncol(your_data)]
)
cbind(your_data, diff_cols)
# x y z y-x z-y
# 1 1 0 2 -1 2
# 2 2 1 3 -1 2
# 3 3 2 4 -1 2
# 4 4 3 5 -1 2
# 5 5 4 6 -1 2
CodePudding user response:
Using dplyr
you could do this:
library(dplyr, warn.conflicts = FALSE)
df1 <- data.frame(x = c(1:5), y = c(0:4), z = c(2:6))
df1 |>
mutate(`y-x` = y - x,
`z-y` = z - y)
#> # A tibble: 5 × 5
#> # Rowwise:
#> x y z `y-x` `z-y`
#> <int> <int> <int> <int> <int>
#> 1 1 0 2 -1 2
#> 2 2 1 3 -1 2
#> 3 3 2 4 -1 2
#> 4 4 3 5 -1 2
#> 5 5 4 6 -1 2
Created on 2022-12-27 with reprex v2.0.2
CodePudding user response:
You could use something like
library(dplyr)
df %>%
mutate(across(x:y,
~. - df[[names(df)[which(names(df) == cur_column()) 1]]],
.names = "{.col}-{names(df)[which(names(df) == .col) 1]}")
)
This returns
x y z x-y y-z
1 1 0 2 1 -2
2 2 1 3 1 -2
3 3 2 4 1 -2
4 4 3 5 1 -2
5 5 4 6 1 -2
Warning message:
Problem while computing `..1 = across(...)`.
ℹ longer object length is not a multiple of shorter object length
but casts a warning which I can't remove.