功能比在R中应用(...,...,范围)更快

时间:2016-01-05 11:06:22

标签: r function for-loop matrix range

我在编写apply()时遇到了问题,这很慢。我的任务是在不使用apply()的情况下给出Matrix的行范围。我尽我所能,但我仍然需要帮助...

这是我到目前为止所得到的:

row.range <- function(X){
  Y <- matrix(0, nrow = nrow(X), ncol = 2)

    for(i in nrow(X)){
    Y[i, 1] <- min(X[i, ])
    Y[i, 2] <- max(X[i, ])
  }
  return(Y)
  print(Y)
}

其中X可以是任何数字矩阵。可悲的是,输出只有0,除了我实际得到正确的最小值和最大值的最后一行。为什么这只适用于最后一行?

我用过的测试:

M <- matrix(sample(1:6, size = 100 * 5, replace = TRUE), ncol = 5)
row.range(X)

非常感谢任何帮助: - )

2 个答案:

答案 0 :(得分:5)

使用较小的可重复示例

Jan 5, 2016 4:07:36 PM org.jinterop.dcom.common.JISystem logSystemPropertiesAndVersion
INFO: j-Interop Version = null

Jan 5, 2016 4:07:36 PM org.jinterop.dcom.common.JISystem logSystemPropertiesAndVersion
INFO: java.runtime.name = Java(TM) SE Runtime Environment
sun.boot.library.path = D:\jdk1.6.0_45\jre\bin
java.vm.version = 20.45-b01
java.vm.vendor = Sun Microsystems Inc.
java.vendor.url = http://java.sun.com/
path.separator = ;
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg = sun.io
sun.java.launcher = SUN_STANDARD
user.country = US
sun.os.patch.level = Service Pack 1
java.vm.specification.name = Java Virtual Machine Specification
user.dir = D:\iefs_ws\OPC_TEST
java.runtime.version = 1.6.0_45-b06
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs = D:\jdk1.6.0_45\jre\lib\endorsed
os.arch = amd64
java.io.tmpdir = C:\Users\irajjad\AppData\Local\Temp\
line.separator = 

java.vm.specification.vendor = Sun Microsystems Inc.
user.variant = 
os.name = Windows 7
sun.jnu.encoding = Cp1252
java.library.path = D:\jdk1.6.0_45\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;D:\jdk1.6.0_45\jre\bin;C:\Program Files\Teradata\Client\15.10\bin;C:\Program Files (x86)\Teradata\Client\15.10\bin;D:\app\IRajjad\product\11.2.0\client_2;c:\Program Files (x86)\Intel\iCLS Client\;c:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;D:\apache-maven-3.2.5\bin;D:\jdk1.7.0_67\bin;D:\path;D:\ArcGIS\Desktop10.3\bin;C:\Program Files (x86)\ArcGIS\DeveloperKit10.2\java\tools\ant\bin;.
java.specification.name = Java Platform API Specification
java.class.version = 50.0
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 6.1
user.home = C:\Users\irajjad
user.timezone = Asia/Karachi
java.awt.printerjob = sun.awt.windows.WPrinterJob
file.encoding = Cp1252
java.specification.version = 1.6
java.class.path = D:\iefs_ws\OPC_TEST\bin;D:\java_opc\org.openscada.jinterop.sdk-R.1.0.0\org.openscada.jinterop.core_2.0.8.201303051454.jar;D:\java_opc\org.openscada.jinterop.sdk-R.1.0.0\org.openscada.jinterop.deps_1.0.0.201303051454.jar;D:\java_opc\org.openscada.utgard.sdk-R.1.0.0\org.openscada.opc.dcom_1.0.0.201303051455.jar;D:\java_opc\org.openscada.utgard.sdk-R.1.0.0\org.openscada.opc.lib_1.0.0.201303051455.jar;D:\eclipse-jee-luna-SR1-win32\eclipse\plugins\org.junit_4.11.0.v201303080030\junit.jar;D:\eclipse-jee-luna-SR1-win32\eclipse\plugins\org.hamcrest.core_1.3.0.v201303031735.jar;D:\java_opc\org.openscada-1.2.0-SNAPSHOT\plugins\org.openscada.external.jcifs_1.2.25.v20140625-1257.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\ch.qos.logback.classic_1.0.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\ch.qos.logback.core_1.0.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\cal10n.api_0.7.4.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.google.gson_2.2.2.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.google.guava_10.0.1.v201203051515.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.jcraft.jzlib_1.1.1.v201205102305.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.antlr_2.7.7.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javassist_3.9.0.GA.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javax.activation_1.1.1.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javax.ejb_3.0.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javax.jms_1.1.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javax.jws_2.0.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javax.transaction_1.1.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javax.xml.rpc_1.1.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javax.xml.soap_1.3.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.javax.xml.stream_1.0.1.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.net.sf.cglib_2.2.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.org.antlr_3.1.3.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.org.aopalliance_1.0.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.org.apache.commons.beanutils_1.8.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.org.apache.commons.collections_3.2.1.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.org.apache.xmlbeans_2.4.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.org.dom4j_1.6.1.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.org.hsqldb_1.8.0.10.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\com.springsource.org.jvnet.staxex_1.0.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\jackson-core-lgpl_1.5.2.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\jackson-mapper-lgpl_1.5.2.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\javax.xml_1.3.4.v201005080400.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\jcl.over.slf4j_1.6.4.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\jsr305_0.1.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\jul.to.slf4j_1.6.4.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\log4j.over.slf4j_1.6.4.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.commons.daemon_1.0.10.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.commons.dbcp_1.4.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.commons.io_2.3.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.commons.lang_2.6.0.v201205030909.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.commons.pool_1.6.0.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.mina.core_2.0.7.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.mina.filter.compression_2.0.7.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.mina.transport.socket.apr_2.0.7.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.tomcat-apr_5.5.23.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.xerces_2.9.0.v201101211617.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.xml.resolver_1.2.0.v201005080400.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.apache.xml.serializer_2.7.1.v201005080400.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.openscada.external.apache.poi_3.7.0.201303051448.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.openscada.external.jbzip2_0.9.1.201303051448.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.openscada.external.jcifs_1.2.25.201303051448.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.openscada.external.logback.default_1.0.0.201303051448.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.openscada.external.odfdom_0.8.7.201303051448.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.openscada.external.osgi.enterprise_4.2.0.201303051448.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.openscada.external.postgresql_9.1.901.201303051448.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.springframework.aop_3.1.2.RELEASE.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.springframework.beans_3.1.2.RELEASE.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.springframework.context_3.1.2.RELEASE.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.springframework.core_3.1.2.RELEASE.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.springframework.jdbc_3.1.2.RELEASE.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.springframework.orm_3.1.2.RELEASE.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.springframework.transaction_3.1.2.RELEASE.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\org.springframework.web_3.1.2.RELEASE.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\slf4j.api_1.6.4.jar;D:\java_opc\org.openscada.external.sdk-R.1.0.0\slf4j.ext_1.6.4.jar;D:\java_opc\bcprov-jdk15on-154.jar;/D:/eclipse-jee-luna-SR1-win32/eclipse/configuration/org.eclipse.osgi/362/0/.cp/;/D:/eclipse-jee-luna-SR1-win32/eclipse/configuration/org.eclipse.osgi/361/0/.cp/
user.name = IRajjad
java.vm.specification.version = 1.0
sun.java.command = org.eclipse.jdt.internal.junit.runner.RemoteTestRunner -version 3 -port 52910 -testLoaderClass org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader -loaderpluginname org.eclipse.jdt.junit4.runtime -test Test:test
java.home = D:\jdk1.6.0_45\jre
sun.arch.data.model = 64
user.language = en
java.specification.vendor = Sun Microsystems Inc.
awt.toolkit = sun.awt.windows.WToolkit
java.vm.info = mixed mode
java.version = 1.6.0_45
java.ext.dirs = D:\jdk1.6.0_45\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
sun.boot.class.path = D:\jdk1.6.0_45\jre\lib\resources.jar;D:\jdk1.6.0_45\jre\lib\rt.jar;D:\jdk1.6.0_45\jre\lib\sunrsasign.jar;D:\jdk1.6.0_45\jre\lib\jsse.jar;D:\jdk1.6.0_45\jre\lib\jce.jar;D:\jdk1.6.0_45\jre\lib\charsets.jar;D:\jdk1.6.0_45\jre\lib\modules\jdk.boot.jar;D:\jdk1.6.0_45\jre\classes
java.vendor = Sun Microsystems Inc.
file.separator = \
java.vendor.url.bug = http://java.sun.com/cgi-bin/bugreport.cgi
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
sun.desktop = windows
sun.cpu.isalist = amd64

Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processOutgoing
INFO: 
 Sending BIND
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processIncoming
INFO: 
 Recieved BIND_ACK
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processOutgoing
INFO: 
 Sending AUTH3
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processOutgoing
INFO: 
 Sending ALTER_CTX
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processIncoming
INFO: 
 Recieved ALTER_CTX_RESP
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processOutgoing
INFO: 
 Sending REQUEST
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processIncoming
INFO: 
 Recieved RESPONSE
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processOutgoing
INFO: 
 Sending BIND
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processIncoming
INFO: 
 Recieved BIND_ACK
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processOutgoing
INFO: 
 Sending AUTH3
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processOutgoing
INFO: 
 Sending REQUEST
Jan 5, 2016 4:07:36 PM rpc.DefaultConnection processIncoming
INFO: 
 Recieved RESPONSE
org.jinterop.dcom.common.JIException: Access is denied.  [0x80070005]
    at org.jinterop.dcom.core.JIRemUnknownServer.call(Unknown Source)
    at org.jinterop.dcom.core.JIRemUnknownServer.addRef_ReleaseRef(Unknown Source)
    at org.jinterop.dcom.core.JIComObjectImpl.addRef(Unknown Source)
    at org.jinterop.dcom.core.JIComServer.createInstance(Unknown Source)
    at org.openscada.opc.lib.da.Server.connect(Server.java:130)
    at Test.test(Test.java:59)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: org.jinterop.dcom.common.JIRuntimeException: Access is denied.  [0x80070005]
    at org.jinterop.dcom.core.JICallBuilder.readResult(Unknown Source)
    at org.jinterop.dcom.core.JICallBuilder.read(Unknown Source)
    at ndr.NdrObject.decode(Unknown Source)
    at rpc.ConnectionOrientedEndpoint.call(Unknown Source)
    at rpc.Stub.call(Unknown Source)
    ... 32 more
16:07:36.716 [OPCSessionDestructor] WARN  org.jinterop.dcom.core.JISession - prepareForReleaseRef: Releasing numInstancesfirsttime + 5 references of IPID: 0000b415-0e50-0000-3e4f-747113678f6a session: -1394010222 , numInstancesfirsttime is 5

您可以尝试已经完全优化的set.seed(123) M <- matrix(sample(1:6, size = 10 * 5, replace = TRUE), ncol = 5) 功能

matrixStats::rowRanges

或者基础R矢量化matrixStats::rowRanges(M) # [,1] [,2] # [1,] 1 6 # [2,] 3 6 # [3,] 3 5 # [4,] 3 6 # [5,] 1 6 # [6,] 1 6 # [7,] 2 5 # [8,] 1 6 # [9,] 2 4 # [10,] 1 6 函数

max.col

另一个半向量化基R使用cbind(M[cbind(1:nrow(M), max.col(-M))], M[cbind(1:nrow(M), max.col(M))]) # [,1] [,2] # [1,] 1 6 # [2,] 3 6 # [3,] 3 5 # [4,] 3 6 # [5,] 1 6 # [6,] 1 6 # [7,] 2 5 # [8,] 1 6 # [9,] 2 4 # [10,] 1 6 结合pmin/pmax(也提供可能的do.call处理),但这需要将矩阵转换为{{1 (不推荐

NA

由于R是一个矢量化语言,因此行操作通常很慢,因此要么尝试向量化,要么使用诸如Rcpp之类的包来编写已编译的C / C ++循环(如第一种情况所做的那样) )

在大多数激进的情况下,您仍然希望使用compiler package

大大优化您的循环

关于你的data.frame循环(正如@PereG已经提到的那样),你有一个语法错误。而不是DF <- as.data.frame(M) cbind(do.call(pmin.int, c(na.rm = TRUE, DF)), do.call(pmax.int, c(na.rm = TRUE, DF))) # [,1] [,2] # [1,] 1 6 # [2,] 3 6 # [3,] 3 5 # [4,] 3 6 # [5,] 1 6 # [6,] 1 6 # [7,] 2 5 # [8,] 1 6 # [9,] 2 4 # [10,] 1 6 这应该是for。否则你只在最后一行操作。

答案 1 :(得分:2)

比较/基准答案/想法和原始代码以供参考。

@{@"53892" : @[@(123),@(124)]}

生成的数据矩阵

代码:

M <- matrix(sample(1:6, size = 1e6 * 5, replace = TRUE), ncol = 5)

验证:

row.range <- function(X){
  Y <- matrix(0, nrow = nrow(X), ncol = 2)

  for(i in 1:nrow(X)){
    Y[i, 1] <- min(X[i, ])
    Y[i, 2] <- max(X[i, ])
  }
  return(Y)
}

testapply <- function(x) {
  t(apply(M,1,function(x) { c(min(x),max(x))} ))
}

testcbind <- function(x) {
  Min <- x[cbind(1:nrow(x),max.col(-x))]
  Max <- x[cbind(1:nrow(x),max.col(x))]
  return(cbind(Min,Max))
}

testpmin <- function(x) {
  DF <- as.data.frame(x)
  cbind(do.call(pmin.int, c(na.rm = TRUE, DF)),
        do.call(pmax.int, c(na.rm = TRUE, DF)))
}

基准:

> head(testpmin(M))
     [,1] [,2]
[1,]    1    5
[2,]    2    6
[3,]    1    6
[4,]    3    6
[5,]    1    5
[6,]    1    4
> head(testcbind(M))
     Min Max
[1,]   1   5
[2,]   2   6
[3,]   1   6
[4,]   3   6
[5,]   1   5
[6,]   1   4
> head(testapply(M))
     [,1] [,2]
[1,]    1    5
[2,]    2    6
[3,]    1    6
[4,]    3    6
[5,]    1    5
[6,]    1    4
> head(row.range(M))
     [,1] [,2]
[1,]    1    5
[2,]    2    6
[3,]    1    6
[4,]    3    6
[5,]    1    5
[6,]    1    4