【问题标题】:Fill missing values in column and then filter在列中填充缺失值,然后过滤
【发布时间】:2021-01-16 01:06:27
【问题描述】:

我正在抓取一些 PDF 数据,在我准备好进入下一步之前需要注意它。列 x1 是唯一 ID,然后 x2 是获取的类型。我需要跨这些类型复制 UID,以便我可以根据类型进行过滤。下面是一些示例数据以及我想要得到的数据。我现在对 type4 特别感兴趣,但以后可能需要其他类型。

我没有尝试过的代码,因为我不确定如何解决这个问题。采集类型是一致的——在示例数据中,总是有 4 种类型,并且 UID 确实出现在 x1 和 x2 列中。

数据如何读入 R:

df <- data.frame(x1 = c(100, "", "", "", "", 101, "", "", "", "", 102, "", "", "", ""),
                 x2 = c(100, "type1", "type2", "type3", "type4", 101, "type1", "type2", "type3", "type4", 102, "type1", "type2", "type3", "type4"),
                 x3 = c(1:15),
                 x4 = c(31:45),
                 x5 = c(100:114))

    x1    x2 x3 x4  x5
1  100   100  1 31 100
2      type1  2 32 101
3      type2  3 33 102
4      type3  4 34 103
5      type4  5 35 104
6  101   101  6 36 105
7      type1  7 37 106
8      type2  8 38 107
9      type3  9 39 108
10     type4 10 40 109
11 102   102 11 41 110
12     type1 12 42 111
13     type2 13 43 112
14     type3 14 44 113
15     type4 15 45 114

所需数据

goal <- data.frame(x1 = c(100, 101, 102),
                   x2 = c("type4", "type4", "type4"),
                   x3 = c(5, 10, 15),
                   x4 = c(35, 40, 45),
                   x5 = c(104, 109, 114))

   x1    x2 x3 x4  x5
1 100 type4  5 35 104
2 101 type4 10 40 109
3 102 type4 15 45 114

我也对解决此问题的不同方法持开放态度,但复制 UID 直到有新的 UID 是我认为效果最好的方法。

【问题讨论】:

    标签: r na missing-data


    【解决方案1】:

    根据要求 - 先填充,然后过滤... 这仅使用tidyverse。我先用 NA 替换了空字符串 ""。

    library(tidyverse)
    df <- data.frame(x1 = c(100, "", "", "", "", 101, "", "", "", "", 102, "", "", "", ""),
                     x2 = c(100, "type1", "type2", "type3", "type4", 101, "type1", "type2", "type3", "type4", 102, "type1", "type2", "type3", "type4"),
                     x3 = c(1:15),
                     x4 = c(31:45),
                     x5 = c(100:114))
    
    df %>% 
      mutate(x1 = as.integer(x1)) %>%
      fill(x1) %>%
      filter(x2 == "type4")
    
    #>    x1    x2 x3 x4  x5
    #> 1 100 type4  5 35 104
    #> 2 101 type4 10 40 109
    #> 3 102 type4 15 45 114
    

    另一种方法是利用数据的明显有序且规则的结构:(仅在本示例中使用基 R)

    x1 <- na.omit(as.integer(df$x1))
    df2 <- subset(df, x2 == "type4")
    df2$x1 <- x1
    
    df2
    #>     x1    x2 x3 x4  x5
    #> 5  100 type4  5 35 104
    #> 10 101 type4 10 40 109
    #> 15 102 type4 15 45 114
    

    【讨论】:

    • 您好,我遇到了一个无法解决的小问题。每隔一段时间,我就会在 x1 中得到 100B 之类的东西。我已经尝试更改您的 mutate 行,将其删除,甚至将其更改为 fill(X1, .direction = "down"),但我没有任何运气。
    • @pkpto39 是在刮掉pdf后导入的数据中吗?下一个问题 - 它总是“B”还是那些独特的字母?在这种情况下,我的 as.integer(x1) 技巧当然会失败。也许尝试mutate(x1 = ifelse(x1 == "", NA , x1)) 等 - 从而直接用 NA 替换空值
    • 我的数据实际上是 MB,它们是随机出现的。不过,我确实需要保持这个角色。例如,100MB 和 100 都可以表示。
    【解决方案2】:

    使用by 进行拆分组合。使用 transform 回收 x1 的第一个元素。

    res <- `rownames<-`(do.call(rbind, by(df, rep(1:(nrow(df)/5), each=5), function(x) {
      transform(x, x1=x1[1])
    })), NULL)
    res
    #     x1    x2 x3 x4  x5
    # 1  100   100  1 31 100
    # 2  100 type1  2 32 101
    # 3  100 type2  3 33 102
    # 4  100 type3  4 34 103
    # 5  100 type4  5 35 104
    # 6  101   101  6 36 105
    # 7  101 type1  7 37 106
    # 8  101 type2  8 38 107
    # 9  101 type3  9 39 108
    # 10 101 type4 10 40 109
    # 11 102   102 11 41 110
    # 12 102 type1 12 42 111
    # 13 102 type2 13 43 112
    # 14 102 type3 14 44 113
    # 15 102 type4 15 45 114
    

    然后随意过滤。

    res[res$x2 %in% "type4", ]
    #     x1    x2 x3 x4  x5
    # 5  100 type4  5 35 104
    # 10 101 type4 10 40 109
    # 15 102 type4 15 45 114
    

    注意: `rownames&lt;-`(..., NULL) 只是化妆品,你也可以省略。

    【讨论】:

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