【问题标题】:R the best way to process data by column with a custom functionR 使用自定义函数按列处理数据的最佳方式
【发布时间】:2017-08-11 16:56:40
【问题描述】:
library(data.table)

df <- structure(list(
continuousNumericOne = c(3.82495116149284, 0.915662542284416, 0.751001771620762, NA, NA, 8.07583989184169, 4.57303752008246, 4.02747047825306, 2.79953011697721, 4.28614794390785), 
catagoricalFactorOne = structure(c(3L, 3L, 3L, NA, 3L, NA, 2L, 2L, 2L, NA), .Label = c("blue", "green", "red"), class = "factor"), 
continuousNumericTwo = c(NA, NA, 2.58285715825289, -2.71316582700148, 3.95645652249594, 1.96862094118233, 4.96960533647993, 6.15199683070215, 3.98091405116921, NA), 
catagoricalFactorTwo = structure(c(3L, 3L, 3L, NA, 3L, 3L, 2L, 2L, 2L, 1L), .Label = c("blue", "orange", "red"), class = "factor"), 
continuousNumericThree = c(3.43332616062442, 2.21448227693603, 2.31889349781533, NA, NA, 3.57539465909581, 3.28076535012702, NA, 3.15063300766727, 2.9556632429251), 
continuousNumericFour = c(7.77131807052585, NA, 6.5830522592014, NA, 7.36003333388333, 8.25217350122047, 7.18282902739316, 8.60641407074177, 4.87689328481095, NA)), 
.Names = c("continuousNumericOne", "catagoricalFactorOne", "continuousFactorTwo", "catagoricalFactorTwo", "continuousNumericThree", "continuousNumericFour"), 
row.names = c(NA, -10L), 
class = c("data.table", "data.frame"))

> df
    continuousNumericOne catagoricalFactorOne continuousFactorTwo catagoricalFactorTwo continuousNumericThree continuousNumericFour
 1:            3.8249512                  red                  NA                  red               3.433326              7.771318
 2:            0.9156625                  red                  NA                  red               2.214482                    NA
 3:            0.7510018                  red            2.582857                  red               2.318893              6.583052
 4:                   NA                   NA           -2.713166                   NA                     NA                    NA
 5:                   NA                  red            3.956457                  red                     NA              7.360033
 6:            8.0758399                   NA            1.968621                  red               3.575395              8.252174
 7:            4.5730375                green            4.969605               orange               3.280765              7.182829
 8:            4.0274705                green            6.151997               orange                     NA              8.606414
 9:            2.7995301                green            3.980914               orange               3.150633              4.876893
10:            4.2861479                   NA                  NA                 blue               2.955663                    NA

如何制作自定义函数来处理数据如下...

  1. 如果列是分类(因子),请将所有 NA 替换为“空白”

  2. 如果该列是连续的(数字),则可以更加灵活地进一步处理数据,例如,首先将数据从 0 缩放到 1,然后根据需要替换 NA,可能使用 -1.1。

我花了很多时间制作清单, 尝试跟踪列名以及给定的列名是否为因子, 尝试通过 apply 方法应用不同的功能,仍然没有运气。

如果有更好的方法,我会全力以赴。

【问题讨论】:

    标签: r function data.table


    【解决方案1】:

    我们可以创建一个函数

    f1 <- function(dat){
     iCat <- which(sapply(dat, is.factor))
     iNum <- which(sapply(dat, is.numeric))
     dat[, (iCat) := lapply(.SD, function(x) {
                  levels(x) <- c(levels(x), "")
                  x[is.na(x)] <- ""
                  x}), .SDcols = iCat]  
      dat[, (iNum) := lapply(.SD, function(x) {
                     x1 <- as.vector(scale(x))
                     x1[is.na(x1)] <- -1.1
                     x1}), .SDcols = iNum][]
     }
    
    f1(df)
    #continuousNumericOne catagoricalFactorOne continuousFactorTwo
    # 1:           0.07257304                  red          -1.1000000
    # 2:          -1.18235090                  red          -1.1000000
    # 3:          -1.25337745                  red          -0.1400258
    # 4:          -1.10000000                               -1.9826003
    # 5:          -1.10000000                  red           0.3378723
    # 6:           1.90619723                               -0.3537288
    # 7:           0.39526068                green           0.6903636
    # 8:           0.15992990                green           1.1017373
    # 9:          -0.36974314                green           0.3463815
    #10:           0.27151063                               -1.1000000
    #    catagoricalFactorTwo continuousNumericThree continuousNumericFour
    # 1:                  red             0.83246346            0.43436598
    # 2:                  red            -1.45562130           -1.10000000
    # 3:                  red            -1.25961447           -0.52487557
    # 4:                                 -1.10000000           -1.10000000
    # 5:                  red            -1.10000000            0.10235154
    # 6:                  red             1.09916272            0.82254218
    # 7:               orange             0.54606741           -0.04069872
    # 8:               orange            -1.10000000            1.10850704
    # 9:               orange             0.30177540           -1.90219245
    #10:                 blue            -0.06423321           -1.10000000
    

    【讨论】:

      【解决方案2】:

      首先,您的示例数据的数字列名称为 "Factor"。所以我提供了我自己的示例数据。

      library(data.table)
      
      set.seed(1)
      df <- data.table(
        num1 = runif(10),
        fac1 = factor(sample(letters, 10)),
        num2 = runif(10),
        fac2 = factor(sample(letters, 10)),
        char = sample(letters, 10)
      )
      

      至于任务,带有通用函数的方法分派符合要求。

      process.factor <- function(x) {
        # Replace with actual logic
        rep_len("f", length(x))
      }
      
      process.numeric <- function(x) {
        # Replace with actual logic
        rep_len("n", length(x))
      }
      
      process.default <- function(x) {
        # Replace with actual logic for "other" classes not specifically handled
        rep_len("d", length(x))
      }
      
      process <- function(x) {
        UseMethod("process")
      }
      

      然后我们只是lapplydata.table 内的列,这导致另一个data.table

      df[, lapply(.SD, process)]
      #     num1 fac1 num2 fac2 char
      #  1:    n    f    n    f    d
      #  2:    n    f    n    f    d
      #  3:    n    f    n    f    d
      #  4:    n    f    n    f    d
      #  5:    n    f    n    f    d
      #  6:    n    f    n    f    d
      #  7:    n    f    n    f    d
      #  8:    n    f    n    f    d
      #  9:    n    f    n    f    d
      # 10:    n    f    n    f    d
      

      【讨论】:

      • 如果有其他列不是因子或数字怎么办? process.default &lt;- function(x) x?
      • process.default 将是您没有为 process.foo 制作的对象的全部内容。您可以制作process.characterprocess.raw,无论您需要什么。并且process 可以留下来作为对UseMethod 的调用。编辑 - 添加process.default 来回答,因为这是正确的做法。
      • 所以你可能需要用process.factor &lt;- function(x) { levels(x) &lt;- c(levels(x), ""); x[is.na(x)] &lt;- ""; x }process.numeric &lt;- function(x) { x &lt;- as.vector(scale(x)); x[is.na(x)] &lt;- -1.1; x }替换
      • 正确。我没有包括您提供的处理步骤,因为它们似乎对问题没有必要。我只是想展示一种如何进行的方法,人们做什么取决于手头的任务。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2011-03-21
      • 2012-12-02
      • 2013-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多