R 基于列类有条件地改变列

R 基于列类有条件地改变列,r,dplyr,pipe,mutate,R,Dplyr,Pipe,Mutate,我的问题是基于之前发布在这里的主题: 假设我有一个tibble,如下所示: id char_var_1 char_var_2 num_var_1 num_var_2 ... x_var_n 1 ... ... ... ... ... 2 ... ... ... ... ... 3 ...

我的问题是基于之前发布在这里的主题:

假设我有一个tibble,如下所示:

id   char_var_1   char_var_2   num_var_1   num_var_2  ... x_var_n
1       ...           ...         ...         ...           ...
2       ...           ...         ...         ...           ...
3       ...           ...         ...         ...           ...
其中,
id
是键,
char\u var\u x
是字符变量,
num\u var\u x
是数字变量。我总共有346列,我想写一个函数来缩放除
id
列之外的所有数值变量。我正在寻找一种优雅的方法,使用管道和dplyr函数对这些列进行变异

显然,以下方法适用于所有数值变量:

pre_process_data <- function(dt)
{
  # scale numeric variables
  dt %>% mutate_if(is.numeric, scale)
}
pre_process_data%mutate_if(is.numeric,scale)
}

但我正在寻找一种方法,从缩放中排除
id
列,保留原始值,同时缩放所有其他数值变量。有一种优雅的方法可以做到这一点吗?

这不是一种规范的方法,但只要稍微做点修改,您就可以通过
mutate_at
实现这一点,方法是使用
对列的整数索引进行变异,该
带有手动构造的列选择条件:

df = data.frame(id = 1:3, a = letters[1:3], b = 2:4)
df %>% 
    mutate_at(vars(which(sapply(., is.numeric) & names(.) != 'id')), scale)

#  id a  b
#1  1 a -1
#2  2 b  0
#3  3 c  1

请尝试以下内容,答案与帖子类似:

“把你感兴趣的专栏变成一个角色,然后把它改回来”怎么样

您可以使用dplyr的


dt%>%select(-id)
不适合你吗?
dt%>%mutate(id=as.character(id))%%>%mutate\u if(is.numeric,scale)%%>%mutate(id=as.numeric(id))
?@JakeKaupp请作为答案提交。我认为在另一列中,多行与
id
列共享相同值的情况下,这不起作用
all(col!=.$id)
在这种情况下将计算为
FALSE
。我认为应该是:
df%>%mutate\u如果(函数(col)是.numeric(col)&!all(col=.$id),scale)
library(dplyr)

# Using @Psidom's example data: https://stackoverflow.com/a/48408027

df %>%
  mutate_if(function(col) is.numeric(col) &
              !all(col == .$id), scale)
#   id a  b
# 1  1 a -1
# 2  2 b  0
# 3  3 c  1
  dt %>%
    mutate(id = as.character(id)) %>% 
    mutate_if(is.numeric, scale) %>% 
    mutate(id = as.numeric(id))
df %>% mutate(across(c(where(is.numeric),-id),scale))