With dplyr
, 我们可以用mutate_at
where f1
, f2
是用于旋转的函数
library(dplyr)
df2 <- df1 %>%
mutate_at(vars(x, y, z), list(rot = f1)) %>%
mutate(col4_rot = f2(col4))
In the devel
版本、使用mutate
with across
df2 <- df1 %>%
mutate(across(vars(x, y, z), f1, names = "{col}_rot"),
col4_rot = f2(col4))
Update
基于更新的功能,我们可以使用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
where
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
in summarise
然后做unnest_wider
and 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
where
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)))
}