2

我有一个data.tableDT其中包含一个C具有满足不等式的实值条目的列0 < x <= 1。我想按例如 10 的间隔对这些条目进行“分组”。具体来说,对于我想要分配值 0.1 的所有值x,对于我想要分配值 0.2 等的所有值C0 < x <=0.1xC0.1 < x <=0.2

下面是我编写的函数,我认为它可以让我这样做(很简单,我对 R 比较陌生!)。

r = function(x,N){

  v = numeric(10)
  for(i in 1:N)
    v[i] = i/N*(x>(i-1)/N & x<=i/N)
   v = v[v!=0]
  return(v)

}

N我需要的间隔数在哪里。但是,代码:

DT = DT[,newC:=r(x=C,N=10)]

给出以下错误:

Warning messages:
1: In v[i] = i/10 * (x > (i - 1)/10 & x <= i/10) :
  number of items to replace is not a multiple of replacement length
2: In v[i] = i/10 * (x > (i - 1)/10 & x <= i/10) :
  number of items to replace is not a multiple of replacement length
...
10: In v[i] = i/10 * (x > (i - 1)/10 & x <= i/10) :
  number of items to replace is not a multiple of replacement length

非常感谢任何帮助!干杯

4

2 回答 2

4

一种(更快的)替代方法是使用findInterval,它的工作与 非常相似cut,但避免了 tofactor和 fromfactor转换

  z1 <- findInterval(x,y)
  z1 <- tail(y,-1)[z1]

还有一些基准测试

cutting <- function(){
  z <- cut(x,y,labels=tail(y,-1))
  #this generates a factor: 
  #you can convert it back to numeric
   z <- as.numeric(levels(z))[z]
  }

finding <- function(){
 z1 <- findInterval(x,y)
 z1 <- tail(y,-1)[z1]
}

microbenchmark(cutting(),finding())


##     Unit: microseconds
##       expr    min       lq   median      uq     max
## 1 cutting() 188.50 192.1175 193.6275 195.821 354.701
## 2 finding()  34.18  35.5140  37.5620  38.763  46.397
于 2013-02-13T22:42:42.397 回答
2

如果您在函数中尝试一行 for 循环,请使用i = 1and说x = C

DT[,1/10 * (C > (1-1)/10 & C <= 1/10)]

你会注意到你得到了一个长度相同的向量C。错误是说您不能将长度 > 1 的向量分配给v[i]. 单步执行您的函数(使用debug,traceback和之类的函数browser)以确保您获得所需的正确输入是一个好主意。

这是使您的功能正常工作的一种方法:

r = function(x,N){

  for(i in 1:N)
    x[x>(i-1)/N & x<=i/N] <- i/N
  return(x)

}

R 也有这样做的内置方法:

#sample data
set.seed(1)
x <- runif(100)
#to organize your data
y <- seq(0,1,.1)
z <- cut(x,y,labels=tail(y,-1))
#this generates a factor: 
#you can convert it back to numeric
z <- as.numeric(levels(z))[z]
于 2013-02-13T13:28:47.383 回答