使用mapply()进行列行比较

时间:2017-07-05 20:47:50

标签: r performance optimization packages

我正在使用两个不同的大型数据集并尝试使用mapply()来使迭代函数正常工作。

目标是从 Data_1 中逐列获取每个数据点,并将其与 Data_2 列中的两个数据点进行比较。因此, Data_1 [1,1] 将仅与 Data_2 [1,1] Data_2 [2,1] 进行比较。为了更清楚, Data_1 中的 data1 列只会与 Data_2 中的 dataA 元素进行比较,因此没有交叉列比较。

Data_1:NxM

  data1       data2       data3      data4
-0.710003   -0.714271   -0.709946   -0.713645
-0.710458   -0.715011   -0.710117   -0.714157
-0.71071    -0.714048   -0.710235   -0.713515
-0.710255   -0.713991   -0.709722   -0.713972

数据_2:PxQ

  dataA       dataB       dataC      dataD
-0.71097    -0.714059   -0.70928    -0.714059
-0.710343   -0.714576   -0.709338   -0.713644

我之前写过基于for() while()循环的算法,但运行时间与原始数据相比太多了。然后,我转移到基于apply()的逻辑,但仍然在我调用的函数中有循环,因此没有加速代码。基于my earlier question,我正在找出使用mapply()更好的方法。

我无法可视化的部分是列到行的比较以及mapply()将如何递归地在其上导航。如何使用mapply()lapply()有效地完成此操作?

任何建议都会有所帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

考虑嵌套的 apply 家庭电话:

  • mapply() - 外部: Data_1 Data_2
  • 的相应列之间的成对迭代
  • sapply - 内部: Data_1 列中每个值的向量迭代,用于元素比较

下面检查每个 Data_1 值是否在 Data_2 的每列的两个值之间:

数据

txt = '  data1       data2       data3      data4
-0.710003   -0.714271   -0.709946   -0.713645
-0.710458   -0.715011   -0.710117   -0.714157
-0.71071    -0.714048   -0.710235   -0.713515
-0.710255   -0.713991   -0.709722   -0.713972'

Data_1 <- read.table(text=txt, header=TRUE)

txt = ' dataA       dataB       dataC      dataD
-0.71097    -0.714059   -0.70928    -0.714059
-0.710343   -0.714576   -0.709338   -0.713644'

Data_2 <- read.table(text=txt, header=TRUE)

<强>代码

check_inbetween <- function(x,y){
  sapply(x, function(i) (i > y[1] & i < y[2]))
}

inbetween_matrix <- mapply(check_inbetween, Data_1, Data_2)

inbetween_matrix
#      data1 data2 data3 data4
# [1,] FALSE FALSE FALSE  TRUE
# [2,]  TRUE FALSE FALSE FALSE
# [3,]  TRUE FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE  TRUE

答案 1 :(得分:0)

这是基于data.table的一种解决方案,但如果您使用的是data.frame或matrix,则应该很容易适应。要达到您想要的效果,您必须使用一个lapply而不是另一个lapply。较高的一个迭代列,这会调用另一个迭代行。

library(data.table)

# it gets all elements of column 'j' to do diff computation
get_column_diff <- function(dt_1, dt_2, j){

        get_point_diff <- function(i){
                # it should return a vector with all differences 
                # in comparison of the point (i,j)
                unlist(dt_1[i, ..j]) - unlist(dt_2[, ..j])
        }


        i_rows <- 1:nrow(dt_1)
        lapply(X=i_rows, FUN=get_point_diff)

}

j_cols <- 1:ncol(Data_1)
lapply(FUN=get_column_diff, dt_1=Data_1, dt_2=Data_2, X=j_cols)

该函数返回一个列表列表,列表的每个元素都是列结果,其元素是一个包含行结果的列表。

关于速度增益,我不能说没有基准比较会有多快,但可能会比任何循环更快。