根据列类

时间:2018-01-23 17:39:09

标签: r dplyr pipe mutate

我的问题基于此处发布的上一个主题:Mutating multiple columns in a data frame

假设我有一个如下步骤:

id   char_var_1   char_var_2   num_var_1   num_var_2  ... x_var_n
1       ...           ...         ...         ...           ...
2       ...           ...         ...         ...           ...
3       ...           ...         ...         ...           ...

其中id是键,char_var_x是字符变量,num_var_x是数字变量。我总共有346列,我想编写一个函数来扩展除id列之外的所有数值变量。我正在寻找一种使用管道和dplyr函数 mutate 这些列的优雅方法。

显然以下适用于所有数字变量:

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

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

4 个答案:

答案 0 :(得分:3)

请尝试以下操作,回答类似于select_if帖子:

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

答案 1 :(得分:2)

这不是一种规范的方法,但是通过一点点破解,您可以使用mutate_at通过使用which使用手动构造的列选择条件使列的整数索引变异来执行此操作:

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

答案 2 :(得分:1)

如何“让你感兴趣的一个角色,然后改变它的方法?”

  dt %>%
    mutate(id = as.character(id)) %>% 
    mutate_if(is.numeric, scale) %>% 
    mutate(id = as.numeric(id))

答案 3 :(得分:0)

您可以使用 dplyr 的 across

df %>% mutate(across(c(where(is.numeric),-id),scale))