С dplyr
мы можем использовать mutate_at
, где f1
, f2
- функции, используемые для вращения
library(dplyr)
df2 <- df1 %>%
mutate_at(vars(x, y, z), list(rot = f1)) %>%
mutate(col4_rot = f2(col4))
В версии devel
используйте mutate
с across
df2 <- df1 %>%
mutate(across(vars(x, y, z), f1, names = "{col}_rot"),
col4_rot = f2(col4))
Обновление
На основе обновленной функции мы можем использовать pmap
library(purrr)
library(stringr)
pmap_dfr(df, rotate) %>%
rename_all(~ str_c(., '_rot')) %>%
bind_cols(df, .)
# A tibble: 5 x 6
# x y z x_rot y_rot z_rot
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 -0.303 1.20 -0.503 -0.0457 0.00799 -1.34
#2 -0.0662 -0.599 1.45 1.35 -0.793 0.0405
#3 0.239 0.953 1.49 -1.39 1.09 -0.288
#4 -0.490 0.0106 -0.622 0.157 0.333 -0.701
#5 0.554 1.08 0.761 -0.748 0.928 -0.802
, где
rotationAngle2 <- 20
rotate <- function(x,y,z){
r = sqrt(x ^ 2 + y ^ 2 + z ^ 2)
phi = atan2(y = y, x = x)
phi = phi + rotationAngle2
theta = acos(z / r)
theta = theta + rotationAngle2
return(list(x = r * cos(phi) * sin(theta),
y = r * sin(phi) * sin(theta),
z = r * cos(theta)))
}
Это также возможно с mutate
library(tidyr)
df %>%
rowwise %>%
mutate(out = list(rotate(x, y, z))) %>%
unnest_wider(c(out))
# A tibble: 5 x 6
# x y z x_rot y_rot z_rot
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 -0.303 1.20 -0.503 -0.0457 0.00799 -1.34
#2 -0.0662 -0.599 1.45 1.35 -0.793 0.0405
#3 0.239 0.953 1.49 -1.39 1.09 -0.288
#4 -0.490 0.0106 -0.622 0.157 0.333 -0.701
#5 0.554 1.08 0.761 -0.748 0.928 -0.802
Или другой вариант - вернуть list
в summarise
, а затем выполнить unnest_wider
и unnest
df %>%
summarise(out = list(rotate(x, y, z))) %>%
unnest_wider(c(out)) %>%
unnest(cols = everything()) %>%
bind_cols(df, .)
# A tibble: 5 x 6
# x y z x_rot y_rot z_rot
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 -0.303 1.20 -0.503 -0.0457 0.00799 -1.34
#2 -0.0662 -0.599 1.45 1.35 -0.793 0.0405
#3 0.239 0.953 1.49 -1.39 1.09 -0.288
#4 -0.490 0.0106 -0.622 0.157 0.333 -0.701
#5 0.554 1.08 0.761 -0.748 0.928 -0.802
, где
rotate <- function(x,y,z){
r = sqrt(x ^ 2 + y ^ 2 + z ^ 2)
phi = atan2(y = y, x = x)
phi = phi + rotationAngle2
theta = acos(z / r)
theta = theta + rotationAngle2
return(list(x_rot = r * cos(phi) * sin(theta),
y_rot = r * sin(phi) * sin(theta),
z_rot = r * cos(theta)))
}