无法合并R中的两个数据帧(VLOOKUP)

时间:2019-05-17 07:26:17

标签: r web-scraping merge

我需要帮助将两个数据帧与R合并。我有点绝望,因为我已经尽了一切努力。任何帮助将不胜感激。

问题是我每天都在抓取网页,我需要将今天的结果与昨天的结果进行比较,以检测是否有任何变化。

在两个数据框中(今天一个,昨天一个)中只有两个变量(页面标题和url),我想将它们合并为一个。

可能的更改是:

  • 更改名称。
  • 更改网址。
  • 新程序(新名称和新网址)。
  • 已删除的程序。

我尝试了合并,投射和熔化,ifelse等等等,但无法解决问题。例如:

yesterday <- read.csv2("Yesterday.csv")
today <- read.csv2("Today.csv")
new <- merge(x = today, y = yesterday, all = TRUE, sort = TRUE)

但是没有理想的结果。我要附加三个文件:

  • Today.csv,今天报废的结果
  • Yesterdat.csv,昨天报废的结果
  • Results.xlsx,具有所需的输出。 Excel中的VLOOKUP,突出显示我要检测的更改(在这种情况下,名称更改)。

我需要针对四个更改选项的解决方案。输出可能会有所不同,我不在乎,但是我需要进行比较才能正确即使您发现这个问题重复了,我也需要链接到另一个问题,因为我没有能够找到它。

谢谢。

1 个答案:

答案 0 :(得分:2)

根据以下评论更新了答案:

library(tidyverse)

bind_rows(

  anti_join(today, yest) %>% 
    mutate(
      label = ifelse(programa %in% yest$programa, 'changed',     'added')
      ),
  anti_join(yest, select(today, programa)) %>%  mutate(label = "deleted")

)

将其应用于整个数据集时,返回以下结果:

# # A tibble: 6 x 3
#   programa                          url                                  label
#   <chr>                             <chr>                                <chr>
# 1 Carrera de Derecho a distancia |~ https://universidadeuropea.es/onlin~ added
# 2 "Carrera de Criminolog\xeda a di~ https://universidadeuropea.es/onlin~ added
# 3 "Carrera Ingenier\xeda Inform\xe~ https://universidadeuropea.es/onlin~ added
# 4 Grado en Derecho a distancia | U~ https://universidadeuropea.es/onlin~ dele~
# 5 "Grado en Criminolog\xeda a dist~ https://universidadeuropea.es/onlin~ dele~
# 6 "Grado Ingenier\xeda Inform\xe1t~ https://universidadeuropea.es/onlin~ dele~

为了检查是否能够在程序中注册更改,我们可以执行以下操作:

yest[22, 2] <- yest[23, 2]

将更改后的数据放入上面的代码中,返回带有附加记录的表,标记为changed

# # A tibble: 7 x 3
#   programa                          url                                  label
#   <chr>                             <chr>                                <chr>
# 1 "M\xe1ster en Direcci\xf3n Hotel~ https://universidadeuropea.es/onlin~ chan~
# 2 Carrera de Derecho a distancia |~ https://universidadeuropea.es/onlin~ added
# 3 "Carrera de Criminolog\xeda a di~ https://universidadeuropea.es/onlin~ added
# 4 "Carrera Ingenier\xeda Inform\xe~ https://universidadeuropea.es/onlin~ added
# 5 Grado en Derecho a distancia | U~ https://universidadeuropea.es/onlin~ dele~
# 6 "Grado en Criminolog\xeda a dist~ https://universidadeuropea.es/onlin~ dele~
# 7 "Grado Ingenier\xeda Inform\xe1t~ https://universidadeuropea.es/onlin~ dele~

说明:

  • bind_rows()中包含的所有内容都组合为单个小标题。只要我们在这里有两个单独的anti_join()语句,并且每个语句都返回自己的小标题,我们就必须rbind将它们合并成一个;
  • anti_join()是一个集合运算,给出两个集合A和B,返回另一个集合C,该集合C是A的子集,但不是B的子集。换句话说,C是A和B之间的差。
    • 当我们调用anti_join(today, yest)时,我们获得today的一个子集,其中的记录 根本不存在于yest中,或者具有program的记录或urlyest相比有所变化。如果mutate()的值与昨天(changed)相同,我们会将这些结果传递到label调用中,并将值programa分配给programa %in% yest$programaurl值已更改。如果programa %in% yest$programaFALSE,则表示该程序名称未出现在yest中,因此它是一个新程序,我们将其标记为added
    • 当我们第二次调用anti_join()时,我们正在寻找yesttoday程序名称之间的区别。换句话说:“ yest中存在哪些程序不在today中?”我们通过查找程序名称不在yest之外的today子集来实现这一点(这就是为什么需要select(today, programa))。如果检测到任何此类记录,则将其标记为deleted

很抱歉,这种解释有些笨拙,但我希望它能帮助您浏览代码。

数据:

tmp <- tempfile()

download.file(
  "https://drive.google.com/uc?authuser=0&id=1scYdZrGYaSDr-TE8IZsy1tKSdLjMn7jt&export=download",
  tmp
  )

today <- read_delim(tmp, delim = ";")

download.file(
  "https://drive.google.com/uc?authuser=0&id=1uJ-ThiKykTjoY1gc3jlBHoab8WAJD-wP&export=download", 
  tmp
  )

yest <- read_delim(tmp, delim = ";")

file.remove(tmp)