比较 R 中的数据帧
Comparing data frames in R
我真的是 R 和 Whosebug 的新手;提前为我的问题道歉。
我有两个数据框
data.frame 1:
Product.ID Description Wholesale.Price
Prod1 Desc1 1.45
Prod Desc2 1.27
Prod3 Desc 3.62
Prod4 Desc4 2.15
Prod5 Desc5 2.87
Prod12 Desc6 2.53
Prod7 Desc7 2.20
Prod8 Desc8 2.60
Prod9 Desc9 3.68
data.frame 2:
Product.ID Description Wholesale.Price
Prod1 Desc1 1.45
Prod2 Desc2 1.27
Prod3 Desc3 3.62
Prod4 Desc4 1.57
Prod5 Desc5 2.87
Prod6 Desc6 2.53
Prod7 Desc7 2.20
Prod8 Desc8 3.21
Prod9 Desc9 1.81
我发现我可以使用 merge(list_1, list_2) 来打印两个数据框的所有 3 列都匹配的位置(这非常酷)。
我正在尝试找到一种方法来打印出基于 Product.ID 的两个数据帧之间的描述和 Wholesale.price 之间存在差异的地方。我什至不确定如何以有意义的方式形象化差异。
非常感谢任何帮助。
让我们重命名您要比较的列:
names(list_1)[3] = "Price1"
names(list_2)[3] = "Price2"
现在我们可以合并并保留两个价格列。
list_both = merge(list_1, list_2)
# calculate differences
list_both$difference = list_both$Price1 - list_both$Price2
# look at the top of the data
head(list_both)
# print out those with a difference
list_both[list_both$difference != 0, ]
为了可视化,我将让您从这里自行探索一下。
前几天我刚刚为某人写了一个 function 来执行这个确切的任务。通过一些修改,它可以在这里使用:
df1 <- data.frame(Product.ID=c('Prod1','Prod','Prod3','Prod4','Prod5','Prod12','Prod7','Prod8','Prod9'), Description=c('Desc1','Desc2','Desc','Desc4','Desc5','Desc6','Desc7','Desc8','Desc9'), Wholesale.Price=c(1.45,1.27,3.62,2.15,2.87,2.53,2.20,2.60,3.68), stringsAsFactors=F );
df2 <- data.frame(Product.ID=c('Prod1','Prod2','Prod3','Prod4','Prod5','Prod6','Prod7','Prod8','Prod9'), Description=c('Desc1','Desc2','Desc3','Desc4','Desc5','Desc6','Desc7','Desc8','Desc9'), Wholesale.Price=c(1.45,1.27,3.62,1.57,2.87,2.53,2.20,3.21,1.81), stringsAsFactors=F );
df1;
## Product.ID Description Wholesale.Price
## 1 Prod1 Desc1 1.45
## 2 Prod Desc2 1.27
## 3 Prod3 Desc 3.62
## 4 Prod4 Desc4 2.15
## 5 Prod5 Desc5 2.87
## 6 Prod12 Desc6 2.53
## 7 Prod7 Desc7 2.20
## 8 Prod8 Desc8 2.60
## 9 Prod9 Desc9 3.68
df2;
## Product.ID Description Wholesale.Price
## 1 Prod1 Desc1 1.45
## 2 Prod2 Desc2 1.27
## 3 Prod3 Desc3 3.62
## 4 Prod4 Desc4 1.57
## 5 Prod5 Desc5 2.87
## 6 Prod6 Desc6 2.53
## 7 Prod7 Desc7 2.20
## 8 Prod8 Desc8 3.21
## 9 Prod9 Desc9 1.81
compare <- function(d1,d2,idcol='id',cols=setdiff(intersect(colnames(d1),colnames(d2)),idcol)) {
com <- intersect(d1[[idcol]],d2[[idcol]]);
d1com <- match(com,d1[[idcol]]);
d2com <- match(com,d2[[idcol]]);
setNames(lapply(cols,function(col) com[d1[[col]][d1com]!=d2[[col]][d2com]]),cols);
}; cmp <- compare(df1,df2,'Product.ID'); cmp;
## $Description
## [1] "Prod3"
##
## $Wholesale.Price
## [1] "Prod4" "Prod8" "Prod9"
cmp
现在包含两个 data.frames 之间不同的 Product.ID
向量,每个非键列一个向量。您可以通过对这些向量进行子集化并合并结果来显示实际差异:
merge(subset(df1,Product.ID%in%cmp$Description),subset(df2,Product.ID%in%cmp$Description),by='Product.ID');
## Product.ID Description.x Wholesale.Price.x Description.y Wholesale.Price.y
## 1 Prod3 Desc 3.62 Desc3 3.62
merge(subset(df1,Product.ID%in%cmp$Wholesale.Price),subset(df2,Product.ID%in%cmp$Wholesale.Price),by='Product.ID');
## Product.ID Description.x Wholesale.Price.x Description.y Wholesale.Price.y
## 1 Prod4 Desc4 2.15 Desc4 1.57
## 2 Prod8 Desc8 2.60 Desc8 3.21
## 3 Prod9 Desc9 3.68 Desc9 1.81
此解决方案的一个优点是它避免了在计算差异之前合并输入的全部内容 data.frames。这样的合并是不必要的,并且会浪费 CPU 和内存,这对于大输入来说可能很重要。
这是一个快速的两行。首先读入来自@bgoldst 的数据:
df1 <- data.frame(Product.ID=c('Prod1','Prod','Prod3','Prod4','Prod5','Prod12','Prod7','Prod8','Prod9'), Description=c('Desc1','Desc2','Desc','Desc4','Desc5','Desc6','Desc7','Desc8','Desc9'), Wholesale.Price=c(1.45,1.27,3.62,2.15,2.87,2.53,2.20,2.60,3.68), stringsAsFactors=F );
df2 <- data.frame(Product.ID=c('Prod1','Prod2','Prod3','Prod4','Prod5','Prod6','Prod7','Prod8','Prod9'), Description=c('Desc1','Desc2','Desc3','Desc4','Desc5','Desc6','Desc7','Desc8','Desc9'), Wholesale.Price=c(1.45,1.27,3.62,1.57,2.87,2.53,2.20,3.21,1.81), stringsAsFactors=F );
现在我们要合并它,但保留所有列:
x <- merge(df1, df2, by = "Product.ID")
现在打印出价格或描述不匹配的列:
x[x$Description.x != x$Description.y | x$Wholesale.Price.x != x$Wholesale.Price.y, ]
Product.ID Description.x Wholesale.Price.x Description.y Wholesale.Price.y
2 Prod3 Desc 3.62 Desc3 3.62
3 Prod4 Desc4 2.15 Desc4 1.57
6 Prod8 Desc8 2.60 Desc8 3.21
7 Prod9 Desc9 3.68 Desc9 1.81
我真的是 R 和 Whosebug 的新手;提前为我的问题道歉。
我有两个数据框
data.frame 1:
Product.ID Description Wholesale.Price
Prod1 Desc1 1.45
Prod Desc2 1.27
Prod3 Desc 3.62
Prod4 Desc4 2.15
Prod5 Desc5 2.87
Prod12 Desc6 2.53
Prod7 Desc7 2.20
Prod8 Desc8 2.60
Prod9 Desc9 3.68
data.frame 2:
Product.ID Description Wholesale.Price
Prod1 Desc1 1.45
Prod2 Desc2 1.27
Prod3 Desc3 3.62
Prod4 Desc4 1.57
Prod5 Desc5 2.87
Prod6 Desc6 2.53
Prod7 Desc7 2.20
Prod8 Desc8 3.21
Prod9 Desc9 1.81
我发现我可以使用 merge(list_1, list_2) 来打印两个数据框的所有 3 列都匹配的位置(这非常酷)。
我正在尝试找到一种方法来打印出基于 Product.ID 的两个数据帧之间的描述和 Wholesale.price 之间存在差异的地方。我什至不确定如何以有意义的方式形象化差异。
非常感谢任何帮助。
让我们重命名您要比较的列:
names(list_1)[3] = "Price1"
names(list_2)[3] = "Price2"
现在我们可以合并并保留两个价格列。
list_both = merge(list_1, list_2)
# calculate differences
list_both$difference = list_both$Price1 - list_both$Price2
# look at the top of the data
head(list_both)
# print out those with a difference
list_both[list_both$difference != 0, ]
为了可视化,我将让您从这里自行探索一下。
前几天我刚刚为某人写了一个 function 来执行这个确切的任务。通过一些修改,它可以在这里使用:
df1 <- data.frame(Product.ID=c('Prod1','Prod','Prod3','Prod4','Prod5','Prod12','Prod7','Prod8','Prod9'), Description=c('Desc1','Desc2','Desc','Desc4','Desc5','Desc6','Desc7','Desc8','Desc9'), Wholesale.Price=c(1.45,1.27,3.62,2.15,2.87,2.53,2.20,2.60,3.68), stringsAsFactors=F );
df2 <- data.frame(Product.ID=c('Prod1','Prod2','Prod3','Prod4','Prod5','Prod6','Prod7','Prod8','Prod9'), Description=c('Desc1','Desc2','Desc3','Desc4','Desc5','Desc6','Desc7','Desc8','Desc9'), Wholesale.Price=c(1.45,1.27,3.62,1.57,2.87,2.53,2.20,3.21,1.81), stringsAsFactors=F );
df1;
## Product.ID Description Wholesale.Price
## 1 Prod1 Desc1 1.45
## 2 Prod Desc2 1.27
## 3 Prod3 Desc 3.62
## 4 Prod4 Desc4 2.15
## 5 Prod5 Desc5 2.87
## 6 Prod12 Desc6 2.53
## 7 Prod7 Desc7 2.20
## 8 Prod8 Desc8 2.60
## 9 Prod9 Desc9 3.68
df2;
## Product.ID Description Wholesale.Price
## 1 Prod1 Desc1 1.45
## 2 Prod2 Desc2 1.27
## 3 Prod3 Desc3 3.62
## 4 Prod4 Desc4 1.57
## 5 Prod5 Desc5 2.87
## 6 Prod6 Desc6 2.53
## 7 Prod7 Desc7 2.20
## 8 Prod8 Desc8 3.21
## 9 Prod9 Desc9 1.81
compare <- function(d1,d2,idcol='id',cols=setdiff(intersect(colnames(d1),colnames(d2)),idcol)) {
com <- intersect(d1[[idcol]],d2[[idcol]]);
d1com <- match(com,d1[[idcol]]);
d2com <- match(com,d2[[idcol]]);
setNames(lapply(cols,function(col) com[d1[[col]][d1com]!=d2[[col]][d2com]]),cols);
}; cmp <- compare(df1,df2,'Product.ID'); cmp;
## $Description
## [1] "Prod3"
##
## $Wholesale.Price
## [1] "Prod4" "Prod8" "Prod9"
cmp
现在包含两个 data.frames 之间不同的 Product.ID
向量,每个非键列一个向量。您可以通过对这些向量进行子集化并合并结果来显示实际差异:
merge(subset(df1,Product.ID%in%cmp$Description),subset(df2,Product.ID%in%cmp$Description),by='Product.ID');
## Product.ID Description.x Wholesale.Price.x Description.y Wholesale.Price.y
## 1 Prod3 Desc 3.62 Desc3 3.62
merge(subset(df1,Product.ID%in%cmp$Wholesale.Price),subset(df2,Product.ID%in%cmp$Wholesale.Price),by='Product.ID');
## Product.ID Description.x Wholesale.Price.x Description.y Wholesale.Price.y
## 1 Prod4 Desc4 2.15 Desc4 1.57
## 2 Prod8 Desc8 2.60 Desc8 3.21
## 3 Prod9 Desc9 3.68 Desc9 1.81
此解决方案的一个优点是它避免了在计算差异之前合并输入的全部内容 data.frames。这样的合并是不必要的,并且会浪费 CPU 和内存,这对于大输入来说可能很重要。
这是一个快速的两行。首先读入来自@bgoldst 的数据:
df1 <- data.frame(Product.ID=c('Prod1','Prod','Prod3','Prod4','Prod5','Prod12','Prod7','Prod8','Prod9'), Description=c('Desc1','Desc2','Desc','Desc4','Desc5','Desc6','Desc7','Desc8','Desc9'), Wholesale.Price=c(1.45,1.27,3.62,2.15,2.87,2.53,2.20,2.60,3.68), stringsAsFactors=F );
df2 <- data.frame(Product.ID=c('Prod1','Prod2','Prod3','Prod4','Prod5','Prod6','Prod7','Prod8','Prod9'), Description=c('Desc1','Desc2','Desc3','Desc4','Desc5','Desc6','Desc7','Desc8','Desc9'), Wholesale.Price=c(1.45,1.27,3.62,1.57,2.87,2.53,2.20,3.21,1.81), stringsAsFactors=F );
现在我们要合并它,但保留所有列:
x <- merge(df1, df2, by = "Product.ID")
现在打印出价格或描述不匹配的列:
x[x$Description.x != x$Description.y | x$Wholesale.Price.x != x$Wholesale.Price.y, ]
Product.ID Description.x Wholesale.Price.x Description.y Wholesale.Price.y
2 Prod3 Desc 3.62 Desc3 3.62
3 Prod4 Desc4 2.15 Desc4 1.57
6 Prod8 Desc8 2.60 Desc8 3.21
7 Prod9 Desc9 3.68 Desc9 1.81