我怎么能让这个R片段更快更R-ish?

zw3*_*324 2 performance r function lapply

来自其他各种语言,我觉得R强大而直观,但我对它的表现并不感到兴奋.所以我决定尝试改进我写的一些片段,并学习如何在R中更好地编码.

这是我写的一个函数,试图确定一个向量是二进制值(两个不同的值还是只有一个值):

isBinaryVector <- function(v) {
  if (length(v) == 0) {
    return (c(0, 1))
  }
  a <- v[1]
  b <- a
  lapply(v, function(x) { if (x != a && x != b) {if (a != b) { return (c()) } else { b = x }}})
  if (a < b) {
    return (c(a, b))
  } else {
    return (c(b, a))
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑:该功能预计将通过一个载体来看看,然后返回c(),如果它不是二进制值,并返回c(a, b)如果是这样,一个是小值,B是较大的一个(如果== B,则刚刚c(a, a)例如,对于.

  A B C
1 1 1 0
2 2 2 0
3 3 1 0
Run Code Online (Sandbox Code Playgroud)

我会lapply这样,isBinaryVector并得到:

$A
[1] 1 1

$B
[1] 1 1

$C
[1] 0 0
Run Code Online (Sandbox Code Playgroud)

在中等大小的数据集上花费的时间(大约1800*3500,其中2/3是二进制值)大约是15秒.该集仅包含浮点数.

反正我还能做得更快吗?

感谢您的任何投入!

And*_*rie 8

您实际上是在尝试编写一个函数,如果向量只有两个唯一值,则返回TRUE,否则返回FALSE.

试试这个:

> dat <- data.frame(
+   A = 1:3,
+   B = c(1, 2, 1), 
+   C = 0
+ )
> 
> sapply(dat, function(x)length(unique(x))==2)
    A     B     C 
FALSE  TRUE FALSE 
Run Code Online (Sandbox Code Playgroud)

接下来,您想获得最小值和最大值.该功能可以range做到这一点 所以:

> sapply(dat, range)
     A B C
[1,] 1 1 0
[2,] 3 2 0
Run Code Online (Sandbox Code Playgroud)

而且你有一些所有的成分来制作一个易于理解的小功能,即使在大量数据上也应该非常快速:

isBinary <- function(x)length(unique(x))==2

binaryValues <- function(x){
  if(isBinary(x)) range(x) else NA
}

sapply(dat, binaryValues)

$A
[1] NA

$B
[1] 1 2

$C
[1] NA
Run Code Online (Sandbox Code Playgroud)

  • @ZiyaoWei只是表明性能通常是程序员的功能,而不是语言!祝你的项目好运. (2认同)