【问题标题】:Recoding multiple variables in R在 R 中重新编码多个变量
【发布时间】:2017-05-07 20:42:51
【问题描述】:

我想在 R 中一次重新编码多个变量。这些变量位于更大的数据框中。以下是一些示例数据:

 z <- data.frame (A = c(1,2,300,444,555),
              B = c(555,444,300,2,1),
              C = c(1,2,300,444,555),
              D = c(1,2,300,444,555))

我想做的是将所有等于 300 的值重新编码为 3、444 为 4、555 为 5。

我认为我可以在列表中执行此操作。这是我尝试过的:

example_list  = list(c("A", "B", "C", "D"))

example_list <- apply(z[,example_list], 1, function(x) ifelse(any(x==555, na.rm=F), 0.5,
                                                              ifelse(any(x==444), 0.25),
                                                              ifelse(any(x==300), 3, example_list)))

我得到这个错误:

Error during wrapup: invalid subscript type 'list'

然后尝试使用“lapply”,我得到了这个错误:

Error during wrapup: '1' is not a function, character or symbol

即使这样,我也不确定这是否是执行此操作的最佳方法...我只是想避免对多个变量逐行执行此操作。任何建议都会很棒,因为我是 R 新手,并不完全理解我做错了什么。

我确实在 SO:Question 上找到了类似的问题,但我不确定如何将其应用于我的具体问题。

【问题讨论】:

    标签: r


    【解决方案1】:

    使用case_when:

    library(dplyr)
    z %>% mutate_all(
        function(x) case_when(
            x == 300 ~ 3,
            x == 444 ~ 4,
            x == 555 ~ 5,
            TRUE ~ x
        )
    )
    
      A B C D
    1 1 5 1 1
    2 2 4 2 2
    3 3 3 3 3
    4 4 2 4 4
    5 5 1 5 5
    

    【讨论】:

      【解决方案2】:

      这是一个基本的 R 尝试,它应该可以很好地扩展并且非常快:

      # set find and replace vectors
      f <- c(300,444,555)
      r <- c(3, 4, 5)
      # replace!
      m   <- lapply(z, function(x) r[match(x,f)] )
      z[] <- Map(function(z,m) replace(m,is.na(m),z[is.na(m)]), z, m)
      
      #  A B C D
      #1 1 5 1 1
      #2 2 4 2 2
      #3 3 3 3 3
      #4 4 2 4 4
      #5 5 1 5 5
      

      【讨论】:

        【解决方案3】:

        这看起来有点笨拙,但确实有效:

        mutate_cols <- c('A', 'B')
        
        z[, mutate_cols] <- as.data.frame(lapply(z[, mutate_cols], function(x) ifelse(x == 300, 3, 
                                                                                      ifelse(x == 444, 4, 
                                                                                             ifelse(x== 555, 5, x)))))
        

        【讨论】:

          【解决方案4】:

          这应该可行。

          library(plyr) 
          new.z<- apply(z, 1, function(x) mapvalues(x, from = c(300, 444, 555), to = c(3, 4, 5)))
          

          【讨论】:

            【解决方案5】:
            z =  data.frame (A = c(1,2,300,444,555),
                             B = c(555,444,300,2,1),
                             C = c(1,2,300,444,555),
                             D = c(1,2,300,444,555))
            
            
            
            library(expss)
            
            to_recode = c("A", "B", "C", "D")
            recode(z[, to_recode]) = c(300 ~ 3, 444 ~ 4, 555 ~ 5)
            

            【讨论】:

            • 感谢 Gregory 的回答。我认为这会很好用,但我似乎没有 expss 库...
            【解决方案6】:

            如果您已经有因子变量并且还想要因子变量作为结果,您可以使用以下代码:

            library(tidyverse)
            z <- data.frame (A = factor(c(1,2,300,444,555)),
                             B = factor(c(555,444,300,2,1)),
                             C = factor(c(1,2,300,444,555)),
                             D = factor(c(1,2,300,444,555)))
            
            new.z <- z %>% 
            mutate_all(function(x) recode_factor(x, "300" = "3", "444" = "4", "555" = "5"))
            

            【讨论】:

              猜你喜欢
              • 2023-04-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-04-07
              • 1970-01-01
              • 2018-07-18
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多