使用R函数确定矩阵中的矢量哪一行

时间:2018-01-01 12:23:15

标签: r matrix

e.g。

a1 <- rbind(c(1,3), c(1,2))
A1 <- rbind(c(1, 2), c(1, 4), c(1,3), c(2, 4))

我想检查A1中哪一行的a1。 在此示例中,返回值应为c(3,1)。

5 个答案:

答案 0 :(得分:2)

对于不测试早期解决方案,我深表歉意,我希望这对您有用:

options(stringsAsFactors =F)

a11 <- do.call("paste0",data.frame(a1))
A11 <- do.call("paste0", data.frame(A1))
which(A11 %in% a11)

<强>输出

> a11
[1] "13" "12"
> A11
[1] "12" "14" "13" "24"
> which(A11 %in% a11)
[1] 1 3

答案 1 :(得分:1)

使用applyduplicated的解决方案。我们的想法是使用apply循环遍历A1中的每一行,每行rbinda1,使用duplicated和{{1}检查是否有任何重复。

any

或者我们可以将所有数字组合成字符串并匹配which(apply(A1, 1, function(x) any(duplicated(rbind(x, a1))))) # [1] 1 3 A1中的字符串。该解决方案的灵感来自PKumar的解决方案。

a1

测试方法

在Dror Bogin的回答的评论部分,OP提出了一个解决方案,即which(apply(A1, 1, toString) %in% apply(a1, 1, toString)) # [1] 1 3 。只有在大矩阵中没有重复项时,此解决方案才有效,例如which(duplicated(rbind(a1 ,A1))) - nrow(a1)

例如,考虑以下矩阵A1,它与A2相同,除了三个额外的行,其中两个是重复的。

A1

A2 <- rbind(c(1, 2), c(1, 4), c(1, 3), c(2, 4), c(5, 8), c(4, 3), c(5, 8)) 的预期输出也应为A2。但是,当我们使用OP的解决方案时,我们将获得7的额外索引。

c(1, 3)

但我的解决方案仍会返回which(duplicated(rbind(a1 ,A2)))-nrow(a1) # [1] 1 3 7

c(1, 3)

最后,如果OP确定没有任何重复。我们可以使用以下代码来进一步简化代码。

which(apply(A2, 1, function(x) any(duplicated(rbind(x, a1)))))
# [1] 1 3

绩效评估

由于OP提到现实矩阵很大,所以值得对这里提出的所有方法进行性能评估。

到目前为止,我们总共有五种方法。

方法1:我提出的“应用复制”方法。

方法2:受PKumar启发的“apply-toString-match”方法

方法3:PKumar提出的“do.call-dataframe-match”方法

方法4:Dror Bogin提出的“for-loop”方法

方法5:提出了“data.table”方法tophcito

下面我使用which(duplicated(rbind(A1, a1), fromLast = TRUE)) # [1] 1 3 包进行效果评估。

microbenchmark

结果表明,方法2是最快的,方法3是第二快的。有意义的是,方法2应该比方法3更快,因为将对象从矩阵转换为数据帧需要一些时间。方法1排名第三,在我看来仍然被认为是一种表现良好的方法。方法5比上述三种方法慢,表明尽管library(microbenchmark) library(data.table) microbenchmark(m1 = {which(apply(A1, 1, function(x) any(duplicated(rbind(x, a1)))))}, m2 = {which(apply(A1, 1, toString) %in% apply(a1, 1, toString))}, m3 = {which(do.call("paste0",data.frame(A1)) %in% do.call("paste0",data.frame(a1)))}, m4 = {v1 = vector() for(i in 1:nrow(A1)){ b = ifelse(all(a1[1,] == A1[i,]),i,NA) d = ifelse(all(a1[2,] == A1[i,]),i,NA) v1 = c(v1,b,d) } v1[!is.na(v1)]}, m5 = {a1_dt <- as.data.table(as.data.frame(a1)) A1_dt <- as.data.table(as.data.frame(A1)) setnames(a1_dt, c("x", "y")) setnames(A1_dt, c("x", "y")) A1_dt[, id := 1:nrow(A1_dt)] result <- merge(A1_dt, a1_dt, by = c("x", "y")) result[, id]}) # Unit: microseconds # expr min lq mean median uq max neval # m1 164.498 191.7435 235.6025 215.1320 237.751 1777.094 100 # m2 71.968 82.2490 101.0790 99.2130 112.064 202.024 100 # m3 140.851 165.5265 197.3618 185.3175 206.908 395.824 100 # m4 4734.462 5107.4095 5450.1260 5348.2450 5535.876 8807.847 100 # m5 1286.684 1394.6360 1591.3651 1508.7560 1674.283 4361.256 100 设计用于处理大数据帧,但在这种情况下,不需要使用data.table进行操作。最后,方法4是最慢的,在这种情况下显示for循环是低效的。

答案 2 :(得分:0)

您必须为 a1 中要检查的每一行添加变量:

Wn = float(1)/HalfSampling
b, a = signal.butter(3, Wn, 'high', analog=False)
BxHPF = signal.filtfilt(b, a, Bxfft)
ByHPF = signal.filtfilt(b, a, Byfft)
plt.plot(BxTime, BxHPF, label='Canal 1', color='r', linewidth=0.5, linestyle="-")
plt.plot(ByTime, ByHPF, label='Canal 3', color='b', linewidth=0.5, linestyle="-")

答案 3 :(得分:0)

使用%in%rowSums的解决方案(应该是改进它的方法):

apply(a1, 1, 
      function(x) which(rowSums(matrix(A1 %in% x, ncol = 2)) == 2))

另一种可能性是使用rowMeans== 1

答案 4 :(得分:0)

可能的解决方案需要添加行号并将两个矩阵合并为数据表。优点是数据表针对速度和大数据进行了优化。

首先,将两个矩阵转换为数据表:

library(data.table)
a1 <- as.data.table(as.data.frame(a1))
A1 <- as.data.table(as.data.frame(A1))
setnames(a1, c("x", "y"))
setnames(A1, c("x", "y"))

让我们添加一个带有rownumbers的附加列:

A1[, id := 1:nrow(A1)]

最后,我们合并了两个表(它们将返回A1的行,其中a1的值出现在其中:

result <- merge(A1, a1, by = c("x", "y"))

由于您只对行号感兴趣,因此请选择:

result[, id]