Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.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
向量版本/对R中等于循环的a进行向量化_R_Loops_Equals Operator - Fatal编程技术网

向量版本/对R中等于循环的a进行向量化

向量版本/对R中等于循环的a进行向量化,r,loops,equals-operator,R,Loops,Equals Operator,我有一个值向量,称之为X,还有一个数据帧,称之为dat.fram。我想运行类似“grep”或“which”的程序来查找dat.fram[,3]的所有索引,这些索引匹配X的每个元素 这是我下面提到的非常低效的for循环。请注意,X中有许多观察值,“match.ind”的每个成员都可以有零个或多个匹配项。此外,dat.fram有100多万次观测。有没有办法在R中使用向量函数来提高这个过程的效率 最后,我需要一个列表,因为我将把列表传递给另一个函数,该函数将从dat.fram检索适当的值 代码: 更新

我有一个值向量,称之为X,还有一个数据帧,称之为dat.fram。我想运行类似“grep”或“which”的程序来查找dat.fram[,3]的所有索引,这些索引匹配X的每个元素

这是我下面提到的非常低效的for循环。请注意,X中有许多观察值,“match.ind”的每个成员都可以有零个或多个匹配项。此外,dat.fram有100多万次观测。有没有办法在R中使用向量函数来提高这个过程的效率

最后,我需要一个列表,因为我将把列表传递给另一个函数,该函数将从dat.fram检索适当的值

代码:


更新:

好的,哇,我刚刚找到了一个很棒的方法。。。真的很滑。想知道它在其他情况下是否有用

### define v as a sample column of data - you should define v to be 
### the column in the data frame you mentioned (data.fram[,3]) 

v = sample(1:150000, 1500000, rep=TRUE)

### now here's the trick: concatenate the indices for each possible value of v,
### to form mybiglist - the rownames of mybiglist give you the possible values
### of v, and the values in mybiglist give you the index points

mybiglist = tapply(seq_along(v),v,c)

### now you just want the parts of this that intersect with X... again I'll
### generate a random X but use whatever X you need to

X = sample(1:200000, 150000)
mylist = mybiglist[which(names(mybiglist)%in%X)]
就这样!作为检查,让我们看一下mylist的前3行:

> mylist[1:3]

$`1`
[1]  401143  494448  703954  757808 1364904 1485811

$`2`
[1]  230769  332970  389601  582724  804046  997184 1080412 1169588 1310105

$`4`
[1]  149021  282361  289661  456147  774672  944760  969734 1043875 1226377
在3处有一个间隙,因为3不出现在X中(即使它出现在v中)。和 与4相对的数字是v中的索引点,其中4出现:

> which(X==3)
integer(0)

> which(v==3)
[1]  102194  424873  468660  593570  713547  769309  786156  828021  870796  
883932 1036943 1246745 1381907 1437148

> which(v==4)
[1]  149021  282361  289661  456147  774672  944760  969734 1043875 1226377
最后,值得注意的是,出现在X中但不在v中的值在列表中不会有条目,但这可能是您想要的,因为它们为NULL

额外注意:您可以使用下面的代码为不在v中的X的每个成员创建NA条目

blanks = sort(setdiff(X,names(mylist)))
mylist_extras = rep(list(NA),length(blanks))
names(mylist_extras) = blanks
mylist_all = c(mylist,mylist_extras)
mylist_all = mylist_all[order(as.numeric(names(mylist_all)))]
相当不言自明:mylist_extras是一个包含您需要的所有其他列表内容的列表(名称是X的值,不包含在名称中(mylist)),列表中的实际条目只是NA)。最后两行首先合并mylist和mylist_extras,然后执行重新排序,以便mylist_中的名称都按数字顺序排列。然后,这些名称应与向量X中的(唯一)值完全匹配

干杯!:)


原帖如下。。。显然,被上述内容取代了

这里有一个tapply的玩具示例,它可能运行得更快。。。我将X和d设置得相对较小,以便您可以看到发生了什么:

X = 3:7
n = 100
d = data.frame(a = sample(1:10,n,rep=TRUE), b = sample(1:10,n,rep=TRUE), 
               c = sample(1:10,n,rep=TRUE), stringsAsFactors = FALSE)

tapply(X,X,function(x) {which(d[,3]==x)})

更新:

好的,哇,我刚刚找到了一个很棒的方法。。。真的很滑。想知道它在其他情况下是否有用

### define v as a sample column of data - you should define v to be 
### the column in the data frame you mentioned (data.fram[,3]) 

v = sample(1:150000, 1500000, rep=TRUE)

### now here's the trick: concatenate the indices for each possible value of v,
### to form mybiglist - the rownames of mybiglist give you the possible values
### of v, and the values in mybiglist give you the index points

mybiglist = tapply(seq_along(v),v,c)

### now you just want the parts of this that intersect with X... again I'll
### generate a random X but use whatever X you need to

X = sample(1:200000, 150000)
mylist = mybiglist[which(names(mybiglist)%in%X)]
就这样!作为检查,让我们看一下mylist的前3行:

> mylist[1:3]

$`1`
[1]  401143  494448  703954  757808 1364904 1485811

$`2`
[1]  230769  332970  389601  582724  804046  997184 1080412 1169588 1310105

$`4`
[1]  149021  282361  289661  456147  774672  944760  969734 1043875 1226377
在3处有一个间隙,因为3不出现在X中(即使它出现在v中)。和 与4相对的数字是v中的索引点,其中4出现:

> which(X==3)
integer(0)

> which(v==3)
[1]  102194  424873  468660  593570  713547  769309  786156  828021  870796  
883932 1036943 1246745 1381907 1437148

> which(v==4)
[1]  149021  282361  289661  456147  774672  944760  969734 1043875 1226377
最后,值得注意的是,出现在X中但不在v中的值在列表中不会有条目,但这可能是您想要的,因为它们为NULL

额外注意:您可以使用下面的代码为不在v中的X的每个成员创建NA条目

blanks = sort(setdiff(X,names(mylist)))
mylist_extras = rep(list(NA),length(blanks))
names(mylist_extras) = blanks
mylist_all = c(mylist,mylist_extras)
mylist_all = mylist_all[order(as.numeric(names(mylist_all)))]
相当不言自明:mylist_extras是一个包含您需要的所有其他列表内容的列表(名称是X的值,不包含在名称中(mylist)),列表中的实际条目只是NA)。最后两行首先合并mylist和mylist_extras,然后执行重新排序,以便mylist_中的名称都按数字顺序排列。然后,这些名称应与向量X中的(唯一)值完全匹配

干杯!:)


原帖如下。。。显然,被上述内容取代了

这里有一个tapply的玩具示例,它可能运行得更快。。。我将X和d设置得相对较小,以便您可以看到发生了什么:

X = 3:7
n = 100
d = data.frame(a = sample(1:10,n,rep=TRUE), b = sample(1:10,n,rep=TRUE), 
               c = sample(1:10,n,rep=TRUE), stringsAsFactors = FALSE)

tapply(X,X,function(x) {which(d[,3]==x)})

您需要将列表传递到的函数是否也应该矢量化?为什么需要分别检查match.ind中的每个项目。你真的需要一次从data.fram获得所有合适的值吗?是的,这里的循环速度会非常慢-如果我正确理解了这个问题,我发布的代码应该满足你的要求:)你需要传递列表的函数也应该矢量化吗?为什么需要分别检查match.ind中的每个项目。你真的需要一次从data.fram获得所有合适的值吗?是的,这里的循环会非常慢-如果我正确理解了这个问题,我发布的代码应该满足你的要求:)我实际上从这个方法得到了与我最初包含的for-loop方法相似的运行时间。编辑:是对原始帖子的回应。工作非常好,速度也很快!非常感谢。我非常确定我可以通过其他脚本重新插入带有空值的行,因为如果
X
中某个值不存在匹配项,我仍然需要为其设置一行。我已经将代码(在“额外注释”下)作为NA填充这些附加位置。如果您愿意,请将NA更改为NULL。。。最重要的是,您创建的最终列表的名称不会遗漏X!中包含的任何内容:)实际上,我从这个方法得到了与我最初包含的for循环方法相似的运行时间。编辑:是对原始帖子的回应。工作非常好,速度也很快!非常感谢。我非常确定我可以通过其他脚本重新插入带有空值的行,因为如果
X
中某个值不存在匹配项,我仍然需要为其设置一行。我已经将代码(在“额外注释”下)作为NA填充这些附加位置。如果您愿意,请将NA更改为NULL。。。最重要的是,您创建的最终列表的名称不会遗漏X!中包含的任何内容:)