我对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和其他函数,但是它们似乎是在比较不同的行而不是不同的单元格。
答案 0 :(得分:2)
首先,我创建数据框。
# 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 :(得分:1)
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)