【问题标题】:Is there a way in R to fill up a dataframe with missing values just like excel vlookup? (SOLVED)R中有没有办法像excel vlookup一样用缺失值填充数据框? (解决了)
【发布时间】:2022-11-06 10:16:48
【问题描述】:

我有一个数据框 df1 是这样的:

Name Category
Apple Fruit
Banana Fruit
Cabbage Vegetable
Apple NA
Orange Fruit
Cabbage NA
Toy Misc
Apple NA

目前,数据框只有名称第一次出现的类别。

但是,我想根据名称填充数据框中的类别以使其像这样:

Name Category
Apple Fruit
Banana Fruit
Cabbage Vegetable
Apple Fruit
Orange Fruit
Cabbage Vegetable
Toy Misc
Apple Fruit

将不胜感激! :)

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用dplyr::group_by,然后使用tidyr::fill

    library(dplyr)
    library(tidyr)
    
    df1 %>% 
      group_by(Name) %>% 
      fill(Category) %>%
      ungroup()
    

    结果:

      Name    Category 
      <chr>   <chr>    
    1 Apple   Fruit    
    2 Banana  Fruit    
    3 Cabbage Vegetable
    4 Apple   Fruit    
    5 Orange  Fruit    
    6 Cabbage Vegetable
    7 Toy     Misc     
    8 Apple   Fruit 
    

    数据:

    df1 <- structure(list(Name = c("Apple", "Banana", "Cabbage", "Apple", 
    "Orange", "Cabbage", "Toy", "Apple"), Category = c("Fruit", "Fruit", 
    "Vegetable", NA, "Fruit", NA, "Misc", NA)), class = "data.frame", row.names = c(NA, 
    -8L))
    

    【讨论】:

    • 我也认为 - df1 %&gt;% group_by(Name) %&gt;% mutate(Category = Category[1]) %&gt;% ungroup()。如果值得的话,就少一个包裹。
    • 这对行的顺序很敏感,而tidyr::fill() 则不是。
    【解决方案2】:

    我们可以使用 dplyr 包中的left_join

    library(dplyr)
    dat %>% 
      left_join(dat %>% 
                  drop_na() %>% 
                  unique(), by = "Name") %>% 
      select(Name,
             Category = Category.y)
         Name  Category
    1   Apple     Fruit
    2  Banana     Fruit
    3 Cabbage Vegetable
    4   Apple     Fruit
    5  Orange     Fruit
    6 Cabbage Vegetable
    7     Toy      Misc
    8   Apple     Fruit
    

    使用 qdapTools 包中的%l% 考虑这个替代方案

    library(qdapTools)
    dat$Category <-  dat[,1] %l% unique(dat[complete.cases(dat), ])  
    dat
         Name  Category
    1   Apple     Fruit
    2  Banana     Fruit
    3 Cabbage Vegetable
    4   Apple     Fruit
    5  Orange     Fruit
    6 Cabbage Vegetable
    7     Toy      Misc
    8   Apple     Fruit
    

    我们也可以使用 qdapTools 包中的lookup

    dat$Category <- lookup(dat[,1],  unique(dat[complete.cases(dat), ]))
    

    【讨论】:

      【解决方案3】:

      在基础 R 中,我们可以使用 match(这非常类似于您熟悉的 excel 的 vlookup

      df1$Category = df1$Category[match(df1$Name, df1$Name)]
      

      如果您想推广到要查找的值不一定是第一次出现的其他情况,我们可以使用

      lookup = df1[!is.na(df1$Category),]
      df1$Category = lookup$Category[match(df1$Name, lookup$Name)]
      

      【讨论】:

      • 请注意,这仅有效,因为第一的instance 有值,这就是 match 每次给出的值。如果行的顺序发生变化,这可能会停止工作。
      • @DanAdams - 这正是 OP 要求的用例。
      • 这是真的,你的回答对于那个问题是完全正确的。我只是为可能没有的未来读者指出精确的相同的数据。
      • @DanAdams 够公平的。不过,概括起来很简单-我将其添加到答案中。
      猜你喜欢
      • 1970-01-01
      • 2020-12-07
      • 2023-03-29
      • 2020-03-07
      • 2017-08-21
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 2017-09-17
      相关资源
      最近更新 更多