【问题标题】:Masking variables in a dataframe based on its column type in R根据 R 中的列类型屏蔽数据框中的变量
【发布时间】:2020-04-27 02:27:11
【问题描述】:

我正在尝试屏蔽用户在 BASE R 中的 data.frame 中请求的变量 (what)。我已经编写了函数 foo 来为 data.frame 中请求的数字变量实现此目标。

但我想知道如何屏蔽字符变量(例如,下面示例中的pid)?

具体来说,下面是我的data.frame、我的函数foo期望的输出

dat <- data.frame(sid = c(33,33,41,42,49,51), pid = c('Bob', 'Bob', 'Jim', 'John', 'Carol smith', 'Cathy'))

#== function `foo`:
foo <- function(data, what){

  f <- function(data, what){

  data[[what]] <- as.numeric(factor(data[[what]], levels = unique(data[[what]])))
  return(data[what])
 }
data[what] <- lapply(what, f, data = data)
return(data)
}
#== Example of use:
 foo(dat, c('sid', 'pid'))

desired.output1 <- data.frame(sid = c(1,1,2, 3,4,5), pid = c('B', 'B', 'Ji', 'Jo', 'Car', 'Cat'))

desired.output2 <- data.frame(sid = c(1,1,2, 3,4,5), pid = c('B', 'B', 'J.1', 'J.2', 'C.1', 'C.2'))

【问题讨论】:

    标签: r regex loops dataframe


    【解决方案1】:

    我们可以对数字列和字符列应用不同的函数。

    foo <- function(data, what){
      dat <- data[what]
      f1 <- function(x) as.numeric(factor(x, levels = unique(x)))
      f2 <- function(x) {
            temp <- substr(x, 1, 1)
            paste0(temp, ave(x, temp, FUN = function(y) match(y, unique(y))))
      }
      num_cols <- names(dat)[sapply(dat, is.numeric)]
      char_cols <- names(dat)[sapply(dat, is.character)]
      if(length(num_cols))  data[num_cols] <- lapply(data[num_cols], f1)
      if(length(char_cols)) data[char_cols] <- lapply(data[char_cols], f2)
      return(data)
    }
    
    foo(dat, c('sid', 'pid'))
    #  sid pid
    #1   1  B1
    #2   1  B1
    #3   2  J1
    #4   3  J2
    #5   4  C1
    #6   5  C2
    
    foo(dat, 'pid')
    
    #  sid pid
    #1  33  B1
    #2  33  B1
    #3  41  J1
    #4  42  J2
    #5  49  C1
    #6  51  C2
    
    
    foo(dat, 'sid')
    #  sid         pid
    #1   1         Bob
    #2   1         Bob
    #3   2         Jim
    #4   3        John
    #5   4 Carol smith
    #6   5       Cathy
    

    【讨论】:

    • @rnorouzian 您只能从函数返回更新的列。请参阅答案中的更新。
    • 是的,没错。您需要分配给那些特定的列。 dat[cols] &lt;- foo(dat, cols)
    • @rnorouzian 你能检查更新的答案吗?这就是你要找的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 2018-05-14
    • 1970-01-01
    相关资源
    最近更新 更多