当在向量中进行索引时出现自我引用

5

在R语言中,有没有一种方法可以从向量内部引用向量?

假设我有一个名称很长的向量:

my.vector.with.a.long.name <- 1:10

不要这样:

my.vector.with.a.long.name[my.vector.with.a.long.name > 5]

希望得到这样的效果:

> my.vector.with.a.long.name[~ > 5]
[1]  6  7  8  9 10

或者使用函数进行索引也很方便:
> my.vector.with.a.long.name[is.even]
[1]  2  4  6  8 10

有没有一个已经支持这个功能的软件包?

2
或者使用制表符来自动补全您的(过长)名称? - rawr
不是很关心我所提供的具体示例的解决方案,只想知道这种语法是否已经得到了支持。 - andrew
1
还没有尝试过,但是可能会使用require(magrittr); my.stupid.name %>% [>5]或类似的方法吗? - Carl Witthoft
1
一个相关的问题,如果您想要实现它,可能会提供一些想法。 - joran
1
@CarlWitthoft 我认为它不能与magrittr一起使用,请参见:http://renkun.me/blog/2014/08/08/difference-between-magrittr-and-pipeR.html - James
显示剩余4条评论
4个回答

8
您可以使用管道符号|,它允许使用.进行自引用:
library(pipeR)
my.vector.with.a.long.name %>>% `[`(.>5)
[1]  6  7  8  9 10
my.vector.with.a.long.name %>>% `[`(.%%2==0)
[1]  2  4  6  8 10

1
是的。我的解决方案是 foo %>>% (.[(.>5)]),我相信它与你的解决方案相同...但你赢得了 CodeGolf :-) - Carl Witthoft

5
< p > Filter 函数可以帮助实现此功能。

my.vector.with.a.long.name <- 1:10
Filter(function(x) x%%2==0, my.vector.with.a.long.name)

或者

is.even <- function(x) x%%2==0
Filter(is.even, my.vector.with.a.long.name)

0

所以,你基本上在问是否可以使用变量名称之外的东西来引用它。简短的答案是否定的。这就是变量名称背后的整个思想。如果你想要一个更短的名称,就给它取一个更短的名字。

更长的答案是,这取决于情况。其实你只是在使用逻辑索引的长形式。为了使它更短/在不必输入那个巨大的名称的情况下多次引用它,只需将其保存在向量中,如下所示:

gt5 <- my.vector.with.a.long.name > 5
[1] FALSE FALSE FALSE FALSE FALSE TRUE...

my.vector.with.a.long.name[gt5]
[1] 6 7 8 9 10

只要函数返回索引或逻辑向量,您就可以使用函数执行相同的操作。

dplyr包允许您执行一些很酷的链接操作,其中您可以使用%.%运算符将操作符的左侧输入到RHS函数调用的第一个参数中。

在dplyr包中使用这种方式非常酷,例如:

data %.% group_by(group.var) %.% summarize(Mean=mean(ID))

改为:

summarize(group_by(data, group.var), Mean=mean(ID)).

1
你可以这样做,但是这样会极大地浪费内存,因为据我所知,当完全没有必要这样做时,一个全新的对象gt5就被创建了。 - Carl Witthoft
是的,gt5会创建一个新的逻辑向量,但显然这只是一个微不足道的例子。如果您要重复使用索引或者创建它很复杂,我喜欢创建这些索引对象。 - MentatOfDune
1
@Carl Witthoft:进行分析,你会发现当你使用上面给出的代码时,完全发生了相同的情况。这与OP的代码完全相同,只是明确地拼写出来。据我所知,内存占用是相同的。 - Joris Meys
1
@JorisMeys但是向量my.vector.with.a.long.name>5在下一次垃圾回收时被删除,而gt5则不会。 - Señor O
@SeñorO 这就是为什么我在课堂上总是强调临时对象的可读性比其他任何东西都更重要,并且应该尽可能地删除。不仅是为了内存问题,还为了避免出现泛型计数器 i 等错误。除此之外,保留它可能是有益的,以避免多次重新计算相同的内容(正如您经常在代码中看到的那样,特别是在 OP 所提到的结构中)。 - Joris Meys
显示剩余3条评论

0

您可以轻松地创建另一个名称更短的对象:

my.vector.with.a.long.name <- 1:10

mm = my.vector.with.a.long.name 

mm
 [1]  1  2  3  4  5  6  7  8  9 10

mm[mm<5]
[1] 1 2 3 4

mm[mm>5]
[1]  6  7  8  9 10

为什么要使用其他包和复杂的代码呢?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接