分配给LHS上的空索引(空方括号x []< ;-) [英] Assignment to empty index (empty square brackets x[]<-) on LHS
问题描述
在查看最近在SO上发布的答案时,我注意到一个陌生的作业陈述。它使用 myVar []<-myValue
的形式,而不是 myVar <-myValue
的常规形式,即左侧的对象用空方括号索引。就我个人而言,我从未见过这样的分配,但是它产生了非常有用的效果-将分配的数据 myValue重塑为 myVar的形状。
While looking at an answer posted recently on SO, I noticed an unfamiliar assignment statement. Instead of the usual form of myVar<- myValue
, it used the form myVar[]<- myValue
, i.e. the object on lefthand side is indexed with empty square brackets. Personally, I had never seen such an assignment, but it had a highly useful effect-- it reshaped the assigned data 'myValue' to the shape of 'myVar'.
我想在我的代码中使用它,因为这使事情变得容易得多。但是<-
的文档似乎对此保持沉默。
I would like to use this in my code as this makes things lot easier. However the documentation for "<-"
seems to be silent on it.
这是一项完善的功能,在任何情况下都可以依靠它来工作吗?
Is this a well established feature and one can rely on it to work in all cases?
我的猜测是这可能是函数调用堆栈的副作用,即在其中调用<-
和 [
顺序,但我不知道如何。有人可以对此有所启示吗?
Also, my guess is that it might be a side effect of a function call stack, i.e. calling <-
and [
in sequence, but I could not figure out how. Can someone throw some light on that?
这里是一个例子-
# A dataframe
df1 <- data.frame(a = 1:4, b = 11:14)
# simple assignment assigns to class of RHS
df1 <- c(21:24, 31:34)
df1
#[1] 21 22 23 24 31 32 33 34
class(df1)
#[1] "integer"
#assignment with [] casts to class of LHS
df1<- data.frame(a = 1:4, b = 11:14)
df1[]<- c(21:24,31:34)
df1
# a b
# 1 21 31
# 2 22 32
# 3 23 33
# 4 24 34
# recycling to preserve shape
df1[]<- c(101:102)
df1
# a b
# 1 101 101
# 2 102 102
# 3 101 101
# 4 102 102
class(df1)
#data.frame
# reshaping
df1<- data.frame(a = 1:4, b = 11:14)
df1[] <- matrix(1:8, 2,4)
df1 #matrix reshaped
class(df1)
#[1] "data.frame"
# flattening
x<- 1:8
x[] <- matrix(1:8,4,2)
x
#[1] 1 2 3 4 5 6 7 8
推荐答案
这是有意记录的功能。如joran所述,文档页面提取在原子向量部分中包括以下内容:
This is an intentional and documented feature. As joran mentioned, the documentation page "Extract" includes this in the "Atomic Vectors" section:
空索引会选择所有值:
An empty index selects all values: this is most often used to replace all the entries but keep the attributes.
但是,对于递归对象( data.frames
或 lists
),则仅为子集对象保留属性。
However, in the case of recursive objects (data.frames
or lists
, for example), the attributes are only kept for the subsetted object. Its parts don't get such protection.
这里是一个例子:
animals <- factor(c('cat', 'dog', 'fish'))
df_factor <- data.frame(x = animals)
rownames(df_factor) <- c('meow', 'bark', 'blub')
str(df_factor)
# 'data.frame': 3 obs. of 1 variable:
# $ x: Factor w/ 3 levels "cat","dog","fish": 1 2 3
df_factor[] <- 'cat'
str(df_factor)
# 'data.frame': 3 obs. of 1 variable:
# $ x: chr "cat" "cat" "cat"
rownames(df_factor)
# [1] "meow" "bark" "blub"
df_factor
保留其行名
属性,但 x
列仅是赋值中使用的字符向量,而不是因子。我们可以通过专门替换其值来保持 x
的类和级别:
df_factor
kept its rownames
attribute, but the x
column is just the character vector used in the assignment instead of a factor. We can keep the class and levels of x
by specifically replacing its values:
df_factor <- data.frame(x = animals)
df_factor$x[] <- 'cat'
str(df_factor)
# 'data.frame': 3 obs. of 1 variable:
# $ x: Factor w/ 3 levels "cat","dog","fish": 1 1 1
因此,对于向量,矩阵和数组,用空子集替换非常安全,因为它们的元素不能具有自己的属性。但是在处理类似列表的对象时需要格外小心。
So replacement with empty subsetting is very safe for vectors, matrices, and arrays, because their elements can't have their own attributes. But it requires some care when dealing with list-like objects.
这篇关于分配给LHS上的空索引(空方括号x []< ;-)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!