比较R中的数据帧

时间:2015-06-04 22:43:35

标签: r compare

我是R和stackoverflow的新手;对我的问题提出道歉。

我有两个数据框

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的两个数据框之间的Description和Wholesale.price之间存在差异的地方。我甚至不确定如何以有意义的方式可视化差异。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:6)

这是一个快速的两个班轮。首先读取@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

答案 1 :(得分:3)

让我们重命名您要比较的列:

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, ]

对于可视化,我会让你从这里自己探索一下。

答案 2 :(得分:2)

我前几天刚给别人写了一个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现在包含Product.ID s的向量,它们在两个data.frame之间有所不同,每个非键列都有一个向量。您可以通过对这些向量进行子集化并合并结果来显示实际差异:

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和内存,这对于大量输入可能很重要。