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?
Here's an example--
# 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
MATLAB has positional input arguments. Many MATLAB functions use an empty numeric array (i.e. []) to indicate that an input argument is undefined, which allows further input arguments to be specified.
This is to indicate that you have an empty "list" as opposed to any variables. It also allows you to invoke specific methods like . append used in your code for subst_words.
Values in a Python dictionary can be accessed by placing the key within square brackets next to the dictionary. Values can be written by placing key within square brackets next to the dictionary and using the assignment operator ( = ). If the key already exists, the old value will be overwritten.
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.
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.
Here's an example:
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With