Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
比较R中大小相等的两个数据帧中的每个单元格是否相等_R_Dataframe - Fatal编程技术网

比较R中大小相等的两个数据帧中的每个单元格是否相等

比较R中大小相等的两个数据帧中的每个单元格是否相等,r,dataframe,R,Dataframe,我有两个数据帧,比如A和B,大小相等(行和列)。我想输出一个数据帧,比如说C,大小相同,所有值都是0或1 C[i,j] = 0, if A[i,j] != B[i,j] C[i,j] = 1, if A[i,j] == B[i,j] 我不想使用循环或ifelse语句,因为我已经成功地做到了这一点,但这需要很长时间。如果有其他直接的方法可以做到这一点,那将非常有帮助。谢谢只需比较两个数据。frames可获得一个大小相同的矩阵,并在单元格中显示一个逻辑值,指示比较结果: A <- mtcar

我有两个数据帧,比如A和B,大小相等(行和列)。我想输出一个数据帧,比如说C,大小相同,所有值都是0或1

C[i,j] = 0, if A[i,j] != B[i,j]
C[i,j] = 1, if A[i,j] == B[i,j]

我不想使用循环或ifelse语句,因为我已经成功地做到了这一点,但这需要很长时间。如果有其他直接的方法可以做到这一点,那将非常有帮助。谢谢

只需比较两个
数据。frame
s可获得一个大小相同的
矩阵,并在单元格中显示一个逻辑值,指示比较结果:

A <- mtcars
B <- mtcars

A == B
要从比较中获取
data.frame
,请使用:

C <- as.data.frame(A == B)
乘以1(如另一个答案中所建议的)更漂亮,可能更有效(避免:

Edit++[添加了基准测试;为保持一致性改进了基准测试]:

基于
data.frame
s的1000万行(约260 MB)的不同答案之间的基准测试

顺便说一句:

我真正喜欢的是现在如何进行一些统计,例如,计算每列(如果使用
rowSums
,则为每行)的不匹配数:

要获得可用于自动检查前提条件的结果(例如,不允许不匹配):

尝试:


C该示例生成一个T/F矩阵,该矩阵在R中可以有效地处理为0/1

x = matrix(1:9, nrow = 3)
y = matrix(9:1, nrow = 3)
x == y
因为在答案中还有一些其他的建议,我想我应该测试一下哪一个是最快的,因为这是问题的要求

这里equals指的是
A==B
解决方案,map_xy指的是
map
解决方案

microbenchmark(equals(x,y), map_xy(x,y), times = 1000)
Unit: nanoseconds
         expr   min    lq      mean  median    uq   max neval
 equals(x, y)   360   399   468.491   459.0   508  3473  1000
 map_xy(x, y) 10909 12114 13506.830 13132.5 14158 77743  1000
看起来equals是一个快得多的选项,但正如
Map
的答案所示,它在更大的数据集上可能表现得更好。因此,我再次使用大小合理的数据进行了测试:

x_big = matrix(1:900000, nrow = 3)
> y_big = matrix(900000:1, nrow = 3)
> microbenchmark(equals(x_big,y_big), map_xy(x_big,y_big), times = 100)
Unit: milliseconds
                 expr        min          lq        mean      median          uq
 equals(x_big, y_big)   1.579069    2.118332    2.515257    2.225747    2.375377
 map_xy(x_big, y_big) 846.172497 1040.383027 1165.354138 1147.239396 1321.166762
        max neval
   21.48414   100
 1489.81884   100
这表明平等仍然是更快的选择

编辑

作为对注释的回应,这里是每个函数的代码。我稍微编辑了这些代码,以将输出转换为data.frame(尽管我个人认为这一步是不必要的)

这会改变基准结果,但不会改变结果:

对于小矩阵:

Unit: microseconds
         expr     min       lq      mean   median       uq      max neval
 equals(x, y)  18.090  20.3205  24.31075  22.0205  23.7285  781.048  1000
 map_xy(x, y) 172.699 186.0775 209.39585 193.3645 204.0220 2646.419  1000
Unit: milliseconds
                 expr       min        lq     mean    median        uq      max
 equals(x_big, y_big)  533.3274  646.0605  744.063  705.4923  871.3479 1067.411
 map_xy(x_big, y_big) 1637.2882 1820.8714 1938.458 1921.2563 2041.0533 2564.669
 neval
   100
   100
对于大型矩阵:

Unit: microseconds
         expr     min       lq      mean   median       uq      max neval
 equals(x, y)  18.090  20.3205  24.31075  22.0205  23.7285  781.048  1000
 map_xy(x, y) 172.699 186.0775 209.39585 193.3645 204.0220 2646.419  1000
Unit: milliseconds
                 expr       min        lq     mean    median        uq      max
 equals(x_big, y_big)  533.3274  646.0605  744.063  705.4923  871.3479 1067.411
 map_xy(x_big, y_big) 1637.2882 1820.8714 1938.458 1921.2563 2041.0533 2564.669
 neval
   100
   100

如果您想要我最初使用的函数,只需取出用于转换为data.frame的代码。

我们可以使用
Map
比较两个data.frame'a'和'B'的对应列

Map(`==`, A, B)

优点是我们在工作区中得到了一个逻辑
向量
列表
,而不是一个
矩阵
。如果数据集真的很大,有矩阵输出可能会限制内存

,评论一下为什么要包括
1*
,而不仅仅是
a==B
好主意,
Map
在内部使用
mapply
,从而避免在内存中构建完整的矩阵。这允许在“每列基础”上进行统计,该基础不使用过多内存,但一次每列仅使用一个逻辑向量。例如:通过
Map(函数(a,b)sum(a!=b),a,b)计算每列的不匹配数
这个答案显然是性能方面的赢家(参见中的基准测试).+1用于您的基准测试。您可以添加
equals
map_xy
函数的代码以实现再现性
?请注意,OP希望比较两个
数据。frame`s而不是两个矩阵,因此结果可能会完全不同(特别是当某些列为字符串列时).THX!已经更新。另外,使用库微基准测试进行基准测试非常简单!所以不确定我是否值得努力!哈哈。你的基准测试没有多大意义。为什么
Map
答案是唯一没有
data.frame
包装的答案?你还主要比较不同
data.frame
w之间的性能与问题IIRC无关的说唱歌手。另外,将其转换为
数据.frame
有什么意义?布尔
数据.frame
如何比布尔
矩阵更好?这里基本上有两种方法
do.call(cbind,Map(`=`,a,B))
vs simply
A==B
@DavidArenburg:Fair points,我将重新考虑我的基准。关于
data.frame
:OP请求它“我想输出一个数据帧,比如C,大小相同,所有值都为0或1”,但事实上,我们应该问他/她为什么不使用矩阵。你希望结果C作为
data.frame
,而不是作为
matrix
?当有人发布答案时,删除问题是不合适的
C <- data.frame(1 * (A == B))
x = matrix(1:9, nrow = 3)
y = matrix(9:1, nrow = 3)
x == y
microbenchmark(equals(x,y), map_xy(x,y), times = 1000)
Unit: nanoseconds
         expr   min    lq      mean  median    uq   max neval
 equals(x, y)   360   399   468.491   459.0   508  3473  1000
 map_xy(x, y) 10909 12114 13506.830 13132.5 14158 77743  1000
x_big = matrix(1:900000, nrow = 3)
> y_big = matrix(900000:1, nrow = 3)
> microbenchmark(equals(x_big,y_big), map_xy(x_big,y_big), times = 100)
Unit: milliseconds
                 expr        min          lq        mean      median          uq
 equals(x_big, y_big)   1.579069    2.118332    2.515257    2.225747    2.375377
 map_xy(x_big, y_big) 846.172497 1040.383027 1165.354138 1147.239396 1321.166762
        max neval
   21.48414   100
 1489.81884   100
equals = function(x,y){
  as.data.frame(x == y)
}

map_xy = function(x,y){
  Map('==', x, y) %>% 
    unlist(.) %>%
    matrix(., nrow = 3) %>%
    as.data.frame(.)
}
Unit: microseconds
         expr     min       lq      mean   median       uq      max neval
 equals(x, y)  18.090  20.3205  24.31075  22.0205  23.7285  781.048  1000
 map_xy(x, y) 172.699 186.0775 209.39585 193.3645 204.0220 2646.419  1000
Unit: milliseconds
                 expr       min        lq     mean    median        uq      max
 equals(x_big, y_big)  533.3274  646.0605  744.063  705.4923  871.3479 1067.411
 map_xy(x_big, y_big) 1637.2882 1820.8714 1938.458 1921.2563 2041.0533 2564.669
 neval
   100
   100
Map(`==`, A, B)