以整洁的方式转换多列
Transform multiple columns the tidy way
不知是否有在管道内转换多列的解决方案。
假设我们有一个包含三列的标题。 iq_pre
和 iq_post
必须在对数刻度上转换并保存到新列中。
library(tidyverse)
library(magrittr)
df <- tibble(
iq_pre = rnorm(10, 100, 15),
iq_post = rnorm(10, 100, 18),
gender = rep(c("m", "f"), each = 5)
)
我知道我可以通过
获得基数 R 的结果
df[c("iq_pre_lg", "iq_post_lg")] <- log(df[c("iq_pre", "iq_post")])
或使用 lapply 遍历列。
我想出的唯一整洁的解决方案是像这样对每一列手动使用 mutate
df %<>%
mutate(iq_pre_lg = log(iq_pre),
iq_post_lg = log(iq_post))
由于要转换的列的名称以相同的字母开头,我也可以使用
df %<>%
mutate_at(vars(starts_with("iq")), funs(lg = log(.)))
但是如果我想转换 20 个不同名称的列怎么办?有没有办法使用 purrr::map
甚至 tidyr::nest
以更优雅的方式解决这个问题?
我们可以使用
df %>%
mutate_at(vars(matches("iq")), log)
matches
的一个优点是它可以在一次调用中匹配多个模式。例如,如果我们需要在以 'iq' 开始 (^
) 或 (|
) 以 'oq' 结束 ($
) 的列上应用该函数, 这可以传递到单个 matches
df %>%
mutate_at(vars(matches('^iq|oq$'), log)
如果列名完全不同,并且n
列有n
种模式,但是如果列的位置还是有一定的顺序,那么列的位置编号就可以了传进了vars
。在当前示例中,'iq' 列是第 1 和第 2 列
df %>%
mutate_at(1:2, log)
同理,如果这20列占据了前20个位置
df %>%
mutate_at(1:20, log)
或者如果位置是1到6、8到12,41:50
df %>%
mutate_at(vars(1:6, 8:12, 41:50), log)
不知是否有在管道内转换多列的解决方案。
假设我们有一个包含三列的标题。 iq_pre
和 iq_post
必须在对数刻度上转换并保存到新列中。
library(tidyverse)
library(magrittr)
df <- tibble(
iq_pre = rnorm(10, 100, 15),
iq_post = rnorm(10, 100, 18),
gender = rep(c("m", "f"), each = 5)
)
我知道我可以通过
获得基数 R 的结果df[c("iq_pre_lg", "iq_post_lg")] <- log(df[c("iq_pre", "iq_post")])
或使用 lapply 遍历列。
我想出的唯一整洁的解决方案是像这样对每一列手动使用 mutate
df %<>%
mutate(iq_pre_lg = log(iq_pre),
iq_post_lg = log(iq_post))
由于要转换的列的名称以相同的字母开头,我也可以使用
df %<>%
mutate_at(vars(starts_with("iq")), funs(lg = log(.)))
但是如果我想转换 20 个不同名称的列怎么办?有没有办法使用 purrr::map
甚至 tidyr::nest
以更优雅的方式解决这个问题?
我们可以使用
df %>%
mutate_at(vars(matches("iq")), log)
matches
的一个优点是它可以在一次调用中匹配多个模式。例如,如果我们需要在以 'iq' 开始 (^
) 或 (|
) 以 'oq' 结束 ($
) 的列上应用该函数, 这可以传递到单个 matches
df %>%
mutate_at(vars(matches('^iq|oq$'), log)
如果列名完全不同,并且n
列有n
种模式,但是如果列的位置还是有一定的顺序,那么列的位置编号就可以了传进了vars
。在当前示例中,'iq' 列是第 1 和第 2 列
df %>%
mutate_at(1:2, log)
同理,如果这20列占据了前20个位置
df %>%
mutate_at(1:20, log)
或者如果位置是1到6、8到12,41:50
df %>%
mutate_at(vars(1:6, 8:12, 41:50), log)