我有2个数据帧,比如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语句,因为我已成功完成,但需要很长时间.如果有任何其他直接的方法来做同样的事情,那将非常有帮助.谢谢
只需将两个data.frame
s进行比较即可获得matrix
具有相同大小的a和单元格中的逻辑,以指示比较结果:
A <- mtcars B <- mtcars A == B
结果(仅显示第一行):
mpg cyl disp hp drat wt qsec vs am gear carb Mazda RX4 TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE Mazda RX4 Wag TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE Datsun 710 TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE Hornet 4 Drive TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
要从data.frame
比较中获得:
C <- as.data.frame(A == B)
您可以使用R 中的TRUE
== 1和FALSE
== 0(如OP要求的那样)将结果显式强制转换为整数:
as.data.frame(lapply(as.data.frame(A == B), as.integer))
乘以1(如另一个答案中所提出的)更漂亮,可能更有效(避免:
as.data.frame(1 * (A == B))
编辑++ [基准添加; 基准改善了一致性]:
基于data.frame
s与10 Mio 的不同答案之间的基准.行(约260 MB)......
library(microbenchmark) # install.packages("microbenchmark") library(data.table) A <- data.frame(col1 = 1:1E7, col2 = rep(c("a string", "another string"), 1E7/2), col3 = 1:1E7, col4 = 1:1E7, col5 = rep(LETTERS[1:10],1E6), stringsAsFactors = FALSE) B <- A B[1,1]=100 # change one cell to create a copy of the data.frame microbenchmark(DF.equals = as.data.frame(A == B), DF.mult = as.data.frame(1 * (A == B)), DF.map = as.data.frame(Map(`==`, A, B)), matrix.equals = A == B, matrix.mult = 1 * (A == B), matrix.map = do.call(cbind, Map(`==`, A, B)), # causes a warning: duplicated levels in factors are deprecated list.map = Map(`==`, A, B), # fast cause it does not construct a matrix but only vectors times = 100)
将该Map()
函数显示为明显的赢家(在我的系统上)比其他变体快两到四倍,结果matrix
比a快得多data.frame
:
Unit: milliseconds expr min lq mean median uq max neval cld DF.equals 627.2541 630.7565 654.0266 635.1831 678.8903 686.0753 100 e DF.mult 743.8531 751.7933 781.1876 796.2282 799.1881 848.2455 100 f DF.map 169.6967 170.5842 176.5944 171.5072 173.5665 223.3354 100 a matrix.equals 294.2570 297.5330 311.8095 299.8093 345.0827 351.9193 100 c matrix.mult 402.6166 406.5279 422.9322 408.3012 453.4484 602.2139 100 d matrix.map 206.2596 208.4230 217.8891 209.8968 211.4139 266.1867 100 b list.map 169.1922 170.5403 175.7539 171.4602 173.3891 224.7062 100 a
BTW:
我真正喜欢的是你现在如何做一些统计数据,例如计算每列不匹配的数量(如果你使用的话,计算行数rowSums
):
colSums(C != TRUE)
要么
colSums(A != B)
获得可用于自动检查前提条件的结果(例如,不允许不匹配):
mpg cyl disp hp drat wt qsec vs am gear carb 0 0 0 0 0 0 0 0 0 0 0
尝试:
C <- data.frame(1 * (A == B))
的1*
是用于接通TRUE
/ FALSE
根据需要至0/1.