【问题标题】:Changing column types with dplyr使用 dplyr 更改列类型
【发布时间】:2019-02-22 20:33:06
【问题描述】:

我需要一些帮助来整理我的数据。我正在尝试将一些整数转换为因子(但不是所有整数都转换为因子)。我想我可以选择有问题的变量,但是如何将它们添加回原始数据集?例如,保留未从我的 raw_data_tbl 中选择的值并使用来自 raw_data_tbl_int 的变异类型

    library(dplyr)

    raw_data_tbl %>% 
    select_if(is.numeric) %>% 
    select(-c(contains("units"), PRO_ALLOW, RTL_ACTUAL, REAL_PRICE, 
           REAL_PRICE_HHU, REBATE, RETURN_UNITS, UNITS_PER_CASE, Profit, STR_COST, DCC, 
           CREDIT_AMT)) %>% 
    mutate_if(is.numeric, as.factor)

【问题讨论】:

  • transformed_raw_data_tbl % mutate_at(vars(contains("units"), PRO_ALLOW, RTL_ACTUAL, REAL_PRICE, REAL_PRICE_HHU, REBATE, RETURN_UNITS, Profit, STR_COST, DCC, CREDIT_AMT), funs(as .nu​​meric)) %>% mutate_at(vars(-contains("units"), -PRO_ALLOW, -RTL_ACTUAL, -REAL_PRICE, -REAL_PRICE_HHU, -REBATE, -RETURN_UNITS, -Profit, -STR_COST, -DCC, -CREDIT_AMT), funs(as.factor))
  • 这段代码把我带到了我想去的地方。保留我想保留为整数的变量的整数类型,并将其余变量更改为因子。

标签: r dplyr


【解决方案1】:

从 CRAN 2020-06-01 发布的 dplyr 1.0.0 开始,范围函数 mutate_at()mutate_if()mutate_all() 已被更通用的 across() 所取代。这意味着您可以只使用mutate()The introductory blog post from April 解释了为什么花了这么长时间才发现。

玩具示例:

library(dplyr)

iris %>%
  mutate(across(c(Sepal.Width, 
                  Sepal.Length),
                factor))

在你的情况下,你会这样做:

library(dplyr)

raw_data_tbl %>% 
  mutate(across(c(is.numeric,
                  -contains("units"),
                  -c(PRO_ALLOW, RTL_ACTUAL, REAL_PRICE, REAL_PRICE_HHU,
                     REBATE, RETURN_UNITS, UNITS_PER_CASE, Profit,
                     STR_COST, DCC, CREDIT_AMT)),
                factor))

【讨论】:

    【解决方案2】:

    您可以改用mutate_at。下面是一个使用 iris 数据框的示例:

    library(dplyr)
    
    iris_factor <- iris %>%
      mutate_at(vars(Sepal.Width, 
                     Sepal.Length), 
                funs(factor))
    

    编辑 08/2020

    从 dplyr 0.8.0 开始,funs() 已弃用。请改用list(),如

    library(dplyr)
    
    iris_factor <- iris %>%
      mutate_at(vars(Sepal.Width, 
                     Sepal.Length), 
                list(factor))
    

    还有证明:

    > str(iris_factor)
    'data.frame':   150 obs. of  5 variables:
     $ Sepal.Length: Factor w/ 35 levels "4.3","4.4","4.5",..: 9 7 5 4 8 12 4 8 2 7 ...
     $ Sepal.Width : Factor w/ 23 levels "2","2.2","2.3",..: 15 10 12 11 16 19 14 14 9 11 ...
     $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
     $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
     $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
    

    【讨论】:

    • 如果使用 tidyverse 那么这将起作用:iris %&gt;% mutate_at(c('Sepal.Width', 'Sepal.Length'), factor)iris %&gt;% mutate_at(vars(Sepal.Width, Sepal.Length), factor)
    【解决方案3】:

    老实说,我会这样做:

    library(dplyr)
    
    df = data.frame("LOC_ID" = c(1,2,3,4),
                    "STRS" = c("a","b","c","d"),
                    "UPC_CDE" = c(813,814,815,816))
    
    df$LOC_ID = as.factor(df$LOC_ID)
    df$UPC_CDE = as.factor(df$UPC_CDE)
    

    【讨论】:

    • 你不需要dplyr来做这样的改变
    • @DaveGruenewald 之所以存在,是因为 OP 在他们的代码中包含它。你当然是对的。 FWIW,我认为您的解决方案更好,我希望 OP 会接受它。
    • 总是喜欢在不需要的时候不依赖包,所以我们的两种解决方案都有时间和地点!
    猜你喜欢
    • 2020-06-09
    • 2015-05-18
    • 1970-01-01
    • 2020-07-24
    • 2015-02-07
    • 1970-01-01
    • 1970-01-01
    • 2014-12-03
    • 1970-01-01
    相关资源
    最近更新 更多