【问题标题】:Merge two data frames with cell mismatches合并两个单元格不匹配的数据框
【发布时间】:2019-03-09 09:57:29
【问题描述】:

我目前卡住了:我已经抓取了一个网站,该网站为同一产品分配了非常不同的名称(即同一产品可以列为“1”、“1 号”、“3 类 - 1 号”)。对于这些值中的每一个,我想分配不同的结果(从具有更好名称的不同站点抓取)。

# Messy code from original website:
df1 <- data.frame(c(1,1,1,1,2,2,2,3,3,3,3,3,4,4,4), c("Number 1", "Number 2", 
                                                      "Category 1", "3", "8",
                                                      "Number 2 - Category 5","1", "Number 4", 
                                                      "Kat 1", "4", "Kat 2", 
                                                      "Number5", "Test", "4","3"))
colnames(df1) <- c("ID", "Category")

> df1
   ID              Category
1   1              Number 1
2   1              Number 2
3   1            Category 1
4   1                     3
5   2                     8
6   2 Number 2 - Category 5
7   2                     1
8   3              Number 4
9   3                 Kat 1
10  3                     4
11  3                 Kat 2
12  3               Number5
13  4                  Test
14  4                     4
15  4                     3

# Code from other site:
df2 <- data.frame(c(1,1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,4,4), c("1", "2", "3", "Category 1",
                                                      "Category 5", "1", "2", "3", "4",
                                                      "Kat 1", "Kat 2", "Kat 3","5",
                                                      "1","2","3","4","Test"), 
                  c(1,2,3,4,5,6,5,8,9,10,11,12,13,14,15,16,17,18))
colnames(df2) <- c("ID", "Category", "Outcome")

> df2
   ID   Category Outcome
1   1          1       1
2   1          2       2
3   1          3       3
4   1 Category 1       4
5   2 Category 5       5
6   2          1       6
7   2          2       5
8   2          3       8
9   3          4       9
10  3      Kat 1      10
11  3      Kat 2      11
12  3      Kat 3      12
13  3          5      13
14  4          1      14
15  4          2      15
16  4          3      16
17  4          4      17
18  4       Test      18

我想保留数据框 1,但分配取自 df2 的“输出”,由 ID 和类别匹配。这可以通过左连接轻松完成,但如您所见,类别级别并不相同。

我一直在考虑重命名关卡,但鉴于我的数据集的大小(约 500,000 行),这似乎不可行,我希望有一个更简单的(grepl、gsub?)解决方案。

我的最终结果应该是这样的:

> df1
   ID              Category Outcome
1   1              Number 1       1
2   1              Number 2       2
3   1            Category 1       4
4   1                     3       3
5   2                     8      NA
6   2 Number 2 - Category 5       5
7   2                     1       6
8   3              Number 4       9
9   3                 Kat 1      10
10  3                     4       9
11  3                 Kat 2      11
12  3               Number5      13
13  4                  Test      18
14  4                     4      17
15  4                     3      16

抱歉这个复杂的例子,我想确保涵盖所有意外情况。这里再解释一下:

只要它有一个类别,通常会以正确的拼写完整列出(即“Kat”将始终显示为“Kat”,而“Category”将始终显示为“Category”)。数字可能会出现在前面的单词“Number”或简单地作为数字本身。如果没有出现数字,我希望它显示 NA - 我稍后将不得不手动添加缺失的数字。

非常感谢您的阅读 - 非常感谢您的帮助!

【问题讨论】:

  • 我认为要处理的情况太多了,但您可以先删除“数字”df1$Category &lt;- sub("Number ", "", df1$Category),然后再左加入merge(df1, df2, all.x = TRUE)

标签: r dataframe merge gsub grepl


【解决方案1】:

这可能会大大简化,但您可以尝试:

library(dplyr)

extr_last_digit <- function(x) substring(x, first = regexpr("(\\d+)(?!.*\\d)", x, perl = T))
extr_cat_digit <- function(x) gsub(".*((?<=Category\\s)\\d+).*|.*((?<=Kat\\s)\\d+).*", "\\1\\2", x, perl = T)

df1 %>%
  mutate(
    join = case_when(
      !grepl("Category|Kat", Category) ~ extr_last_digit(Category),
      TRUE ~ paste0("Category ", extr_cat_digit(Category)))
  ) %>%
  left_join(df2 %>%
              mutate(
                join = case_when(
                  !grepl("Category|Kat", Category) ~ extr_last_digit(Category),
                  TRUE ~ paste0("Category ", extr_cat_digit(Category))
                ),
                Category = NULL), 
            by = c("ID", "join")
  ) %>%
  select(-join)

输出:

   ID              Category Outcome
1   1              Number 1       1
2   1              Number 2       2
3   1            Category 1       4
4   1                     3       3
5   2                     8      NA
6   2 Number 2 - Category 5       5
7   2                     1       6
8   3              Number 4       9
9   3                 Kat 1      10
10  3                     4       9
11  3                 Kat 2      11
12  3               Number5      13
13  4                  Test      18
14  4                     4      17
15  4                     3      16

基本上,它的作用是在 df 中创建一个具有相同结构的 join 列 - 如果它没有找到任何提及 CategoryKat,它使用最后提到的数字合并,否则它会粘贴单词 Category 和单词 CategoryKat 之后提到的数字。

这也适用于单词Test,因为如果它没有找到任何数字,它只会使用整个字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-22
    • 2022-01-27
    • 1970-01-01
    • 2016-08-25
    • 2021-03-04
    • 1970-01-01
    • 2021-03-30
    • 2021-02-24
    相关资源
    最近更新 更多