【问题标题】:How to replace values and words using ifelse / lag / mutate in the same function?如何在同一函数中使用 ifelse / lag / mutate 替换值和单词?
【发布时间】:2018-08-14 00:58:57
【问题描述】:

我有类似的数据。

v1 <- c("Fail", 20, 30, "Out", NA, 32, 33, 10)
v2 <- c(10, NA, NA, "Out", "Fail", 34, 35, 30)
df <- data.frame(v1,v2)

我也需要转换这个数据框。这样'words'或者NA就是前面的信息,或者前面的信息没有,我需要后面再去取信息。

我如何在R 中使用现代编程实际做到这一点?根据this link,我正在做这样的事情。

df <- df %>% mutate(v11 = ifelse(v1 %in% "Fail", lag(),
                     ifelse(v1 %in% "Out", lag()),
                     ifelse(is.na(v1) %in% lag(), v1)))

【问题讨论】:

  • 为什么 v1[5]NA 变成 32 而不是 30?
  • 对不起,我编辑了。
  • @MikeH。似乎是,但不是100%相同。即使在这里也有好的和新的答案。甚至有话在df.

标签: r dataframe dplyr tidyverse


【解决方案1】:

你可以使用tidyverse:

library(tidyverse)
df%>%
   replace(array(grepl("\\D",as.matrix(df)),dim(df)),NA)%>%
   mutate_all(~as.numeric(as.character(.x)))%>%
   fill(v1:v2,.direction ="down")%>%
   fill(v1:v2,.direction = "up")
  v1 v2
1 20 10
2 20 10
3 30 10
4 30 10
5 30 10
6 32 34
7 33 35
8 10 30

【讨论】:

    【解决方案2】:

    来自zoo,na.locf的解决方案

    df[which(df=="Fail" | df=='Out')]='NA'
    zoo::na.locf(zoo::na.locf(df),fromLast=T)
      v1 v2
    1 20 10
    2 20 10
    3 30 10
    4 30 10
    5 30 10
    6 32 34
    7 33 35
    8 10 30
    

    【讨论】:

      【解决方案3】:

      这是fill的选项

      library(tidyverse)
      df %>%
           mutate_all(funs(as.numeric(as.character(.)))) %>% 
           fill(v1, v2) %>%
           fill(v1, .direction = 'up')
      #   v1 v2
      #1 20 10
      #2 20 10
      #3 30 10
      #4 30 10
      #5 30 10
      #6 32 34
      #7 33 35
      #8 10 30
      

      【讨论】:

        【解决方案4】:

        首先使用read.table 将非数字字符串转换为NA,给出df0,然后使用na.approx。这给出了一个矩阵。如果您想要一个数据框,请在结果上使用as.data.frame

        library(zoo)
        
        df0 <- read.table(text = paste(df$v1, df$v2), na.strings = c("NA", "Out", "Fail"))
        na.approx(df0, method = "constant", rule = 2)
        

        给予:

             V1 V2
        [1,] 20 10
        [2,] 20 10
        [3,] 30 10
        [4,] 30 10
        [5,] 30 10
        [6,] 32 34
        [7,] 33 35
        [8,] 10 30
        

        如果需要,我们可以像这样使用 magrittr 来表达:

        library(matrittr)
        library(zoo)
        
        df %$%
          paste(v1, v2) %>%
          read.table(text = ., na.strings = c("NA", "Out", "Fail")) %>%
          na.approx(method = "constant", rule = 2)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-01-12
          • 1970-01-01
          • 1970-01-01
          • 2020-12-03
          • 1970-01-01
          • 2020-10-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多