我有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]
Run Code Online (Sandbox Code Playgroud)
我不想使用循环或ifelse语句,因为我已成功完成,但需要很长时间.如果有任何其他直接的方法来做同样的事情,那将非常有帮助.谢谢
只需将两个data.frames进行比较即可获得matrix具有相同大小的a和单元格中的逻辑,以指示比较结果:
A <- mtcars
B <- mtcars
A == B
Run Code Online (Sandbox Code Playgroud)
结果(仅显示第一行):
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
Run Code Online (Sandbox Code Playgroud)
要从data.frame比较中获得:
C <- as.data.frame(A == B)
Run Code Online (Sandbox Code Playgroud)
您可以使用R 中的TRUE== 1和FALSE== 0(如OP要求的那样)将结果显式强制转换为整数:
as.data.frame(lapply(as.data.frame(A == B), as.integer))
Run Code Online (Sandbox Code Playgroud)
乘以1(如另一个答案中所提出的)更漂亮,可能更有效(避免:
as.data.frame(1 * (A == B))
Run Code Online (Sandbox Code Playgroud)
编辑++ [基准添加; 基准改善了一致性]:
基于data.frames与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)
Run Code Online (Sandbox Code Playgroud)
将该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
Run Code Online (Sandbox Code Playgroud)
BTW:
我真正喜欢的是你现在如何做一些统计数据,例如计算每列不匹配的数量(如果你使用的话,计算行数rowSums):
colSums(C != TRUE)
Run Code Online (Sandbox Code Playgroud)
要么
colSums(A != B)
Run Code Online (Sandbox Code Playgroud)
获得可用于自动检查前提条件的结果(例如,不允许不匹配):
mpg cyl disp hp drat wt qsec vs am gear carb
0 0 0 0 0 0 0 0 0 0 0
Run Code Online (Sandbox Code Playgroud)
尝试:
C <- data.frame(1 * (A == B))
Run Code Online (Sandbox Code Playgroud)
的1*是用于接通TRUE/ FALSE根据需要至0/1.