r - 用循环记录转换R中的许多变量
问题描述
我有一个数据框,它有一个用于诊断的二进制变量(第 1 列)和 165 个营养变量(第 2-166 列),用于 n=237。我们称这个数据集为 nutr_all。我需要创建 165 个新变量来获取每个营养变量的自然对数。所以,我想得到一个包含 331 列的数据框 - 第 1 列 = 诊断,第 2-166 列 = 营养变量,第 167-331 列 = 对数转换后的营养变量。我希望这些变量取旧变量的名称,但末尾带有“_log”
我尝试过使用 for 循环和 mutate 命令,但是,我对 r 不是很精通,所以我很挣扎。
for (nutr in (nutr_all_nomiss[,2:166])){
nutr_all_log <- mutate(nutr_all, nutr_log = log(nutr) )
}
当我这样做时,它只会创建一个名为 nutr_log 的新变量。我知道我需要让 r 知道“nutr_log”中的“nutr”是 for 循环中的变量名,但我不确定如何。
解决方案
对于最近遇到此页面的任何人,该页面dplyr::across()
于 2020 年底推出,它正是为这项任务而构建的 - 一次将相同的转换应用于许多列。
下面是一个简单的解决方案。
如果您需要选择要转换的列,请通过在 R 控制台中运行来查看tidyselect辅助函数。?tidyr_tidy_select
library(tidyverse)
# create vector of column names
variable_names <- paste0("nutrient_variable_", 1:165)
# create random data for example
data_values <- purrr::rerun(.n = 165,
sample(x=100,
size=237,
replace = T))
# set names of the columns, coerce to a tibble,
# and add the diagnosis column
nutr_all <- data_values %>%
set_names(variable_names) %>%
as_tibble() %>%
mutate(diagnosis = 1:237) %>%
relocate(diagnosis, .before = everything())
# use across to perform same transformation on all columns
# whose names contain the phrase 'nutrient_variable'
nutr_all_with_logs <- nutr_all %>%
mutate(across(
.cols = contains('nutrient_variable'),
.fns = list(log10 = log10),
.names = "{.col}_{.fn}"))
# print out a small sample of data to validate
nutr_all_with_logs[1:5, c(1, 2:3, 166:168)]
就个人而言,与其将所有列添加到数据框中,我更愿意创建一个仅包含转换后的值的新数据框,并更改列名:
logs_only <- nutr_all %>%
mutate(across(
.cols = contains('nutrient_variable'),
.fns = log10)) %>%
rename_with(.cols = contains('nutrient_variable'),
.fn = ~paste0(., '_log10'))
logs_only[1:5, 1:3]
推荐阅读
- php - 如何使用 PHP 版本的 Google Sheet API v4 合并单元格
- python - 编辑后的操纵杆代码未接收输入
- sql - 如何编写一个基本的 SQL 函数来匹配具有最大值和最小值范围的值?
- java - Apache cxf + soap 匿名寻址
- c# - 如何使用 jquery 在 html 页面中调用 web api?
- c# - 使用 CSVHelper 动态映射嵌套对象
- spring-boot - JPA 映射问题
- c++ - QUdpSocket - 数据报被接收两次,为什么?
- python - 找出随机单词是否构成由最后一个字母和第一个字母连接的单词序列(单词足球)
- c - 无符号函数必须返回一些东西吗?