【问题标题】:Conditionally mutate columns based on column class基于列类有条件地改变列
【发布时间】:2018-07-02 15:04:47
【问题描述】:

我的问题基于之前发布的主题: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 函数变异这些列。

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

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

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

【问题讨论】:

  • dt %&gt;% select(-id) 不适合你吗?
  • dt %&gt;% mutate(id = as.character(id)) %&gt;% mutate_if(is.numeric, scale) %&gt;% mutate(id = as.numeric(id)) ?
  • @JakeKaupp 请作为答案提交。

标签: r pipe dplyr


【解决方案1】:

试试下面,答案类似于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

【讨论】:

  • 我认为这在存在另一列的许多行与id 列共享相同值的情况下不起作用。在这种情况下,all(col != .$id) 将评估为 FALSE。我认为应该是:df %&gt;% mutate_if(function(col) is.numeric(col) &amp; !all(col == .$id), scale)
【解决方案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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      你可以使用dplyr的across

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

      【讨论】:

        猜你喜欢
        • 2018-11-04
        • 1970-01-01
        • 2018-07-04
        • 2020-04-24
        • 1970-01-01
        • 2016-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多