R:如何定位和比较两个 CSV 文本文件之间的特定元素
R: How to locate and compare a particular element between two CSV text files
我发现了一些类似的问题,例如 this one (about comparing attributes in XML files), this one (about a case where the compared values are numeric) and (关于获取两个文件之间不同的列数),但与此特定问题无关。
我有两个 CSV 文本文件,其中许多(但不是所有)行都相等。这些文件在列上具有相同数据类型的相同数量的列,但它们没有相同数量的行。两个文件的行数都在 120K 左右,并且两个文件都有一些行不在另一个文件中。
这些文件的简化版本如下所示。
文件 1:
PROFILE.ID,CITY,STATE,USERID
2265,Miami,Florida,EL4950
4350,Nashville,Tennessee,GW7420
5486,Durango,Colorado,BH9012
R719,Flagstaff,Arizona,YT7460
Z551,Flagstaff,Arizona,ML1451
文件 2:
PROFILE.ID,CITY,STATE,USERID
1173,Nashville,Tennessee,GW7420
2265,Miami,Florida,EL4950
R540,Flagstaff,Arizona,YT7460
T216,Durango,Colorado,BH9012
在实际文件中,第一个文件中的许多 USERID
值也可以在第二个文件中找到(但有些可能不存在)。此外,虽然所有用户的 USERID
值都没有改变,但他们的 PROFILE.ID
可能已经改变。
问题是我必须找到 PROFILE.ID
已更改的行。
我想我必须使用以下步骤序列在 R 中分析它:
- 将两个文件作为数据帧加载到 R Studio
- 遍历第一个文件(有更多行)的
USERID
列
- 在第二个文件中搜索在第一个文件
中找到的每个 USERID
- Return 第二个文件
对应的PROFILE.ID
- 将返回值与第一个文件中的内容进行比较
- 输出
PROFILE.ID
值不同的行
我正在考虑编写如下所示的代码,但不确定是否有更好的方法来完成此操作。
library(tidyverse)
con1 <- file("file1.csv", open = "r")
con2 <- file("file2.csv", open = "r")
file1 <- read.csv(con1, fill = F, colClasses = "character")
file2 <- read.csv(con2, fill = F, colClasses = "character")
for (i in seq(nrow(file1))) {
profIDFile1 <- file1$PROFILE.ID[i]
userIDFile1 <- file1$USERID[i]
profIDRowFile2 <- filter(file2, USERID == userIDFile1)
profIDFile2 <- profIDRowFile2$PROFILE.ID
if (profIDFile1 != profIDFile2) {
output < - profIDRowFile2
}
}
write.csv(output, file='result.csv', row.names=FALSE, quote=FALSE)
close(con1)
close(con2)
问题:
R 中是否有可以进行此类比较的包,或者在 R 脚本中完成此比较的好方法是什么?
我想你可以通过简单的连接来做到这一点:
library(dplyr)
full_join(file1, file2, by = "USERID") %>%
filter(PROFILE.ID.x != PROFILE.ID.y)
# PROFILE.ID.x CITY.x STATE.x USERID PROFILE.ID.y CITY.y STATE.y
# 1 4350 Nashville Tennessee GW7420 1173 Nashville Tennessee
# 2 5486 Durango Colorado BH9012 T216 Durango Colorado
# 3 R719 Flagstaff Arizona YT7460 R540 Flagstaff Arizona
这表明那三个 USERID
行具有不同的 PROFILE.ID
字段。 (.x
来自 file1
,.y
来自 file2
。)
该测试不能很好地处理其中缺少的 ID,因此您可以添加如下逻辑:
full_join(file1, file2, by = "USERID") %>%
filter(is.na(PROFILE.ID.x) | is.na(PROFILE.ID.y) |
PROFILE.ID.x != PROFILE.ID.y)
# PROFILE.ID.x CITY.x STATE.x USERID PROFILE.ID.y CITY.y STATE.y
# 1 4350 Nashville Tennessee GW7420 1173 Nashville Tennessee
# 2 5486 Durango Colorado BH9012 T216 Durango Colorado
# 3 R719 Flagstaff Arizona YT7460 R540 Flagstaff Arizona
# 4 Z551 Flagstaff Arizona ML1451 <NA> <NA> <NA>
第四行表示 file2
中缺少 ID。这很可能是一个小样本数据集的产物(这在 SO 上很好 :-),我不确定这对你来说是否有趣或有意义。
我们可以用 base R
subset(merge(file, file2, by = 'USERID'), PROFILE.ID.x != PROFILE.ID.y)
我发现了一些类似的问题,例如 this one (about comparing attributes in XML files), this one (about a case where the compared values are numeric) and
我有两个 CSV 文本文件,其中许多(但不是所有)行都相等。这些文件在列上具有相同数据类型的相同数量的列,但它们没有相同数量的行。两个文件的行数都在 120K 左右,并且两个文件都有一些行不在另一个文件中。
这些文件的简化版本如下所示。
文件 1:
PROFILE.ID,CITY,STATE,USERID
2265,Miami,Florida,EL4950
4350,Nashville,Tennessee,GW7420
5486,Durango,Colorado,BH9012
R719,Flagstaff,Arizona,YT7460
Z551,Flagstaff,Arizona,ML1451
文件 2:
PROFILE.ID,CITY,STATE,USERID
1173,Nashville,Tennessee,GW7420
2265,Miami,Florida,EL4950
R540,Flagstaff,Arizona,YT7460
T216,Durango,Colorado,BH9012
在实际文件中,第一个文件中的许多 USERID
值也可以在第二个文件中找到(但有些可能不存在)。此外,虽然所有用户的 USERID
值都没有改变,但他们的 PROFILE.ID
可能已经改变。
问题是我必须找到 PROFILE.ID
已更改的行。
我想我必须使用以下步骤序列在 R 中分析它:
- 将两个文件作为数据帧加载到 R Studio
- 遍历第一个文件(有更多行)的
USERID
列 - 在第二个文件中搜索在第一个文件 中找到的每个
- Return 第二个文件 对应的
- 将返回值与第一个文件中的内容进行比较
- 输出
PROFILE.ID
值不同的行
USERID
PROFILE.ID
我正在考虑编写如下所示的代码,但不确定是否有更好的方法来完成此操作。
library(tidyverse)
con1 <- file("file1.csv", open = "r")
con2 <- file("file2.csv", open = "r")
file1 <- read.csv(con1, fill = F, colClasses = "character")
file2 <- read.csv(con2, fill = F, colClasses = "character")
for (i in seq(nrow(file1))) {
profIDFile1 <- file1$PROFILE.ID[i]
userIDFile1 <- file1$USERID[i]
profIDRowFile2 <- filter(file2, USERID == userIDFile1)
profIDFile2 <- profIDRowFile2$PROFILE.ID
if (profIDFile1 != profIDFile2) {
output < - profIDRowFile2
}
}
write.csv(output, file='result.csv', row.names=FALSE, quote=FALSE)
close(con1)
close(con2)
问题: R 中是否有可以进行此类比较的包,或者在 R 脚本中完成此比较的好方法是什么?
我想你可以通过简单的连接来做到这一点:
library(dplyr)
full_join(file1, file2, by = "USERID") %>%
filter(PROFILE.ID.x != PROFILE.ID.y)
# PROFILE.ID.x CITY.x STATE.x USERID PROFILE.ID.y CITY.y STATE.y
# 1 4350 Nashville Tennessee GW7420 1173 Nashville Tennessee
# 2 5486 Durango Colorado BH9012 T216 Durango Colorado
# 3 R719 Flagstaff Arizona YT7460 R540 Flagstaff Arizona
这表明那三个 USERID
行具有不同的 PROFILE.ID
字段。 (.x
来自 file1
,.y
来自 file2
。)
该测试不能很好地处理其中缺少的 ID,因此您可以添加如下逻辑:
full_join(file1, file2, by = "USERID") %>%
filter(is.na(PROFILE.ID.x) | is.na(PROFILE.ID.y) |
PROFILE.ID.x != PROFILE.ID.y)
# PROFILE.ID.x CITY.x STATE.x USERID PROFILE.ID.y CITY.y STATE.y
# 1 4350 Nashville Tennessee GW7420 1173 Nashville Tennessee
# 2 5486 Durango Colorado BH9012 T216 Durango Colorado
# 3 R719 Flagstaff Arizona YT7460 R540 Flagstaff Arizona
# 4 Z551 Flagstaff Arizona ML1451 <NA> <NA> <NA>
第四行表示 file2
中缺少 ID。这很可能是一个小样本数据集的产物(这在 SO 上很好 :-),我不确定这对你来说是否有趣或有意义。
我们可以用 base R
subset(merge(file, file2, by = 'USERID'), PROFILE.ID.x != PROFILE.ID.y)