Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于某列上的rep函数查找R中的行中的序列_R_Data.table - Fatal编程技术网

基于某列上的rep函数查找R中的行中的序列

基于某列上的rep函数查找R中的行中的序列,r,data.table,R,Data.table,我试图根据某个列的rep函数在一行中查找一个0序列。下面是我迄今为止最好的尝试,它抛出了一个错误。我尝试使用一个apply循环,但失败得很惨,我真的不想使用for循环,除非我不得不这样做,因为我的真实数据集大约有800000行。我试着寻找解决方案,但似乎什么也找不到,为此我花了几个小时,但运气不佳。我还附加了所需的输出。 library(data.table) TEST_DF <- data.table(INDEX = c(1,2,3,4),


我试图根据某个列的rep函数在一行中查找一个0序列。下面是我迄今为止最好的尝试,它抛出了一个错误。我尝试使用一个apply循环,但失败得很惨,我真的不想使用for循环,除非我不得不这样做,因为我的真实数据集大约有800000行。我试着寻找解决方案,但似乎什么也找不到,为此我花了几个小时,但运气不佳。我还附加了所需的输出。

library(data.table)

TEST_DF <- data.table(INDEX = c(1,2,3,4),
                      COL_1 = c(0,0,0,0),
                      COL_2 = c(0,0,2,5),
                      COL_3 = c(0,0,0,0),
                      COL_4 = c(0,2,0,1),
                      DAYS  = c(4,4,2,2))

IN_FUN <- function(x, y)
{
  x <- rle(x)

  if( max(as.numeric(x$lengths[x$values == 0])) >= y )
  {
    "Y"
  }
  else
  {
    "N"
  }
}

TEST_DF$DEFINITION <- apply(TEST_DF[, c(2:5), with = FALSE], 1, 
                            FUN = IN_FUN(TEST_DF[, c(2:5), with = FALSE], TEST_DF$DAYS))

DESIRED <- TEST_DF <- data.table(P_ID = c(1,2,3,4),
                                 COL_1 = c(0,0,0,0),
                                 COL_2 = c(0,0,2,5),
                                 COL_3 = c(0,0,0,0),
                                 COL_4 = c(0,2,0,1),
                                 DAYS  = c(4,4,2,2).
                                 DEFINITION = c("Y","N","Y","N"),
                                 INDEX = c(2,NA,4,NA)
库(data.table)

测试DF我想我更了解这一点,因为问题已经编辑了一些。这有循环,因此它可能不是最佳速度,但set语句应该对此有所帮助。它仍然具有data.table提供的一些加速功能

#Combined all column values in giant string
TEST_DF[ , COL_STRING := paste(COL_1,COL_2,COL_3,COL_4,COL_5,COL_6,COL_7,COL_8,COL_9,COL_10,COL_11,COL_12,sep=",")]
TEST_DF[ , COL_STRING := paste0(COL_STRING,",")]

#Using the Days variable, create a string to be searched
for (i in 1:nrow(TEST_DF))
  set(TEST_DF,i=i,j="FIND",value=paste(rep("0,",TEST_DF[i]$DAYS),sep="",collapse=""))

#Find where pattern starts. A negative 1 value means it does not exist
for (i in 1:nrow(TEST_DF))
  set(TEST_DF,i=i,j="INDEX",value=regexpr(TEST_DF[i]$FIND,TEST_DF[i]$COL_STRING,fixed=TRUE)[1])

#Define DEFINITION
TEST_DF[ , DEFINITION := 1*(INDEX != -1)]

#Find where pattern starts. A negative 1 value means it does not exist
require(stringr)
for (i in 1:nrow(TEST_DF))
  set(TEST_DF,i=i,j="INDEX",value=str_count(substr(TEST_DF[i]$COL_STRING,1,TEST_DF[i]$INDEX),","))

#Clean up variables
TEST_DF[ , INDEX := INDEX + DEFINITION*2L]
TEST_DF[INDEX==0L, INDEX := NA_integer_]

用一些数学技巧就能做到这一点。我创建了一个二进制矩阵,其中一个元素如果最初为0,则为1,否则为0。然后,对于每一行,我将行中的第n个元素设置为(n-1个元素+第n个元素)乘以第n个元素。在这个变换矩阵中,一个元素的值等于0(包括这个元素)的连续先前元素的数量


m您可以探索IRanges包。我刚刚将测试数据集定义为
data.frame
,因为我不熟悉
data.table
。然后我将其扩展到您的数据集大小800000:

TEST_DF <- TEST_DF[sample(nrow(TEST_DF), 800000, replace=TRUE),]

TEST_DF在您的编辑中,为什么第7行定义值是1而不是零?其中有非零值。对于这些新数据,
索引
值应该是什么?并且
列似乎与每行中找到的零的数量不对应。请考虑一下由于我解释不好而产生的一点误解。“天数”列不是第1列到第12列的结果。DAYS列所说的是在COL_1和COL_12之间的每一行中查找序列rep(0,DAYS[i])。查看第1行,我们希望看到第1列到第12列中是否有10个0。对于第7行,我们希望看到第1列和第12列之间有3个连续的0,第6列和第8列之间有3个连续的0。最后,让我们假设第9行,我们正在寻找9个连续的0,在列1和列12之间没有这样的出现,因此定义在这里得到一个0或“N”。编写一个干净的
for
循环与
apply
循环没有什么错(几乎没有时间损失)。写些对你来说更容易的。谢谢你,本。不得不稍微调整一下,因为不管出于什么原因,行m[m==1]感谢您的解决方案,Michael。本是第一个找到正确答案的人,所以我给了他一个绿色的记号。我很感谢您为感兴趣的用户提供不同的解决方案,但恐怕我只能给出1个绿色勾号。不过我要提到的是,我用传统的install.packages方式下载IRanges软件包时遇到了麻烦,所以我用谷歌搜索了它,下面几行代码为其他感兴趣的用户安装了该软件包:source(“谢谢你,Mike,谢谢你的努力和你的解决方案。我相信你的解决方案会引起其他用户的兴趣,因为它对我学习R很有用。我喜欢Ben的解决方案的简单性,所以我给了他一个绿色记号,尽管你的努力也值得一个绿色记号。
m<-as.matrix(TEST_DF[, 2:(ncol(TEST_DF)-1L)])
m[m==1]<-2
m[m==0]<-1
m[m!=1]<-0

for(i in 2:ncol(m)){
  m[,i]=(m[,i-1]+m[,i])*m[,i]
}

# note the use of with=FALSE -- this forces ncol to be evaluated
#   outside of TEST_DF, leading the result to be used as a
#   column number instead of just evaluating to a scalar
m<-as.matrix(cbind(m, Days=TEST_DF[,ncol(TEST_DF),with=FALSE]))
indx<-apply(m[,-ncol(m)] >= m[,ncol(m)],1,function(x) match(TRUE,x) )

TEST_DF$DEFINITION<-ifelse(is.na(indx),0,1)
TEST_DF$INDEX<-indx-TEST_DF$DAYS+2
TEST_DF <- TEST_DF[sample(nrow(TEST_DF), 800000, replace=TRUE),]
library(IRanges)
m <- t(as.matrix(TEST_DF[,2:13]))
l <- relist(Rle(m), PartitioningByWidth(rep(nrow(m), ncol(m))))
r <- ranges(l)
validRuns <- width(r) >= TEST_DF$DAYS
TEST_DF$DEFINITION <- sum(validRuns) > 0
TEST_DF$INDEX <- drop(phead(start(r)[validRuns], 1)) + 1L