比较两个数据帧并在R中打印出更新的行



我对R很陌生,我正在努力解决这个看起来很简单的问题,但我不知道该怎么做。我正在尝试比较两个数据帧,打印出其中一个而不是另一个中的行,还打印另一个列表/数据帧,其中只有一个单元格更新。

df1
firstname  lastname email
Grace       Holly   hollyoaks@yahoo.com
Trish       Edison  edisontrish@gmail.com
df2
firstname lastname  email
Grace     Holly     rickyoaks@yahoo.com
Frederick Sam       sammic@gmail.com

我想做的第一件事是获取df2中而不是df1中的行,我就是这样做的:

require(sqldf)
df2NotIndf1 <- sqldf('SELECT * FROM df2 EXCEPT SELECT * FROM df1')

这给了我输出:

`firstname lastname  email`
`Frederick Sam       sammic@gmail.com`

现在,我想要的是一种方法,通过注意名字和姓氏相同,但电子邮件不同,将第一行作为自己的输出。

所以,我想要一种打印出来的方法:

firstname  lastname  email
Grace     Holly     rickyoaks@yahoo.com

我看了compare((函数、merge和其他函数,但它们似乎是在进行比较,以发现不同的行,而不是不同的单元格。

首先,我创建数据帧。

# Create data frames
df1 <- read.table(text = "firstname  lastname email
Grace       Holly   hollyoaks@yahoo.com
Trish       Edison  edisontrish@gmail.com", ,
header = TRUE, stringsAsFactors = FALSE)
df2 <- read.table(text = "firstname lastname  email
Grace     Holly     rickyoaks@yahoo.com
Frederick Sam       sammic@gmail.com", 
header = TRUE, stringsAsFactors = FALSE)

接下来,我加载dplyr

# Load libraries
library(dplyr)

在这里,我执行反联接以查找df2中不在df1中的行。

# Perform antijoin
df3 <- df2 %>% anti_join(df1, by = c("firstname", "lastname"))
#   firstname lastname            email
# 1 Frederick      Sam sammic@gmail.com

然后,我将原始的两个数据帧绑定在一起,删除之前标识为仅出现在df2中的行,然后使用除一列之外的所有列检查重复项。如果除一列外,所有列中都有重复项,则保留这些行。

# Bind two data frames together
# Remove those only appearing in df2
# Filter to those with duplicates in all but one column
df1 %>% 
bind_rows(df2) %>% 
anti_join(df3) %>% 
filter((duplicated(firstname, lastname) + duplicated(email, lastname) + duplicated(firstname, email)) == ncol(df1) - 1)
#   firstname lastname               email
# 1     Grace    Holly rickyoaks@yahoo.com

我目前正在考虑一种更简洁的方式来编写filter行,它可以概括为任意数量的列。

1(如果您正在寻找一种方法来列出那些名字和姓氏都在df1和df2中但电子邮件不同的人,那么:

sqldf("select df1.*, df2.email email2 
from df1 
join df2 on df1.firstname = df2.firstname and 
df1.lastname = df2.lastname and 
df1.email <> df2.email")

下面给出了df1记录和与df2不同的电子邮件。

firstname lastname               email              email2
1     Grace    Holly hollyoaks@yahoo.com rickyoaks@yahoo.com

2(或基本解决方案为:

subset(merge(df1, df2, by = 1:2), email.x != email.y)

备注

以可复制形式使用的输入是:

Lines1 <- "firstname  lastname email
Grace       Holly   hollyoaks@yahoo.com
Trish       Edison  edisontrish@gmail.com"
Lines2 <- "firstname lastname  email
Grace     Holly     rickyoaks@yahoo.com
Frederick Sam       sammic@gmail.com"
df1 <- read.table(text = Lines1, header = TRUE, as.is = TRUE, strip.white = TRUE)
df2 <- read.table(text = Lines2, header = TRUE, as.is = TRUE, strip.white = TRUE)

相关内容

  • 没有找到相关文章

最新更新