Adding string to variable name - r

I have a variable a=0.01
I then create a matrix b<-matrix(data=NA,ncol=2,nrow=9)
I would like to rename this matrix by adding the value stored in a to its name.
The results should be b_0.01

I bet there are more elegant ways to achieve what you need, but this seems to work:
assign(x = paste("b", a, sep = "_"), value = b)
Edit following #Roland's comment:
rm(b)
Please note that I address your question in a narrow sense. As pointed out by both #Roland and #Paul Hiemstra, there may be more general aspects of the work-flow that could be fruitful to consider as well.

You can use assign to get this done:
a = 0.01
b = matrix(data=NA,ncol=2,nrow=9)
assign(sprintf('b_%s', a), b)
b_0.01
In general, I would avoid creating data objects like this. In stead, I would use list's to create, store and manipulate groups of objects.

Related

Convert nested list to dataframe in R

This question sounds like it has already been asked on SO, but I ask it anyway because the existing answers did not work for me and I'm not sure how better to phrase it, as I am new to R and don't entirely grasp the intricacies of its data types.
Time for a minimal example. I am looking for a transformation of target such that targetObject is exactly equal to referenceObject.
reference = '{"airport":[{"name":"brussels","loc":{"lat":"1","lon":"2"}}],"parking":[{"name":"P1"}]}'
target = '{"airport":{"name":"brussels","loc":{"lat":"1","lon":"2"}},"parking":{"name":"P1"}}'
referenceObject = jsonlite::fromJSON(reference)$airport
x = jsonlite::fromJSON(target)$airport
# Transformation
targetObject = do.call(rbind.data.frame, x)
# Currently prints FALSE, should become TRUE
results_same = identical(referenceObject, targetObject)
print(results_same)
I would expect this to be very simple in any language, but R seems to handle the nested loc lists very differently depending on the shape of the outer object airport.
I managed to find a solution by serializing back to JSON. It's not elegant but at least it works.
# Transformation
targetObject = jsonlite::fromJSON(jsonlite::toJSON(list(x), auto_unbox = TRUE))
For now I will not mark this answer as correct because it's more of a workaround than an ideomatic solution.

Selecting rows of a dataframe fullfilling an specific condition in R

First of all, I have to say that this is my first post. Despite of having look for the answer using the search toolbox it might be possible that I passed over the right topic without realizing myself, so just in case sorry for that.
Having said that, my problem is the following one:
I have a data table composed by several columns.
I have to select the
rows that are fullfilling one specific condition ex.
which(DT_$var>value, arr.ind = T)) or which(DT_$var>value &&
DT_$var2>value2, arr.ind = T))
I have to keep these columns in a new
data frame.
My approach was the following one but it is not working, probably because I did not understand the loops correctly:
while (i in nrow(DT)) {
if(DT$var[i]>value){
DT_aux[i]=DT[i]
i<-i+1
}
}
Error in if (DT$value[i] > 45) { : argument is of length zero
I hope that you can help me
There is a very good chance that you want to use dplyr and it's filter function. It would work like this:
library(dplyr)
DT %>% filter(var>value && var2>value2)
You don't need to use DT$var and DT$var2 here; dplyr knows what you mean when you refer to variables.
You can, of course, do the same with base R, but this kind of work is exactly what dplyr was made for, so sticking with base R, in this case, is just masochism.

R - Operate on a column w/o explicitely reassigning it?

I'm often writing things like:
dataframe$this_column <- as.Date(dataframe$this_column)
That is, when changing some column in my data frame [table], I'm constantly writing the column twice. Is there some function that allows me to directly change the data frame w/o explicitly reassigning it? Say: ch(dataframe$this_column, as.Date())
EDIT: While similar, the potential duplicate is not the same. I am not looking for a way to shorten self-referential reassignments. I'm looking to avoid the explicit reassignment all together. The answer I accepted here is an appropriate solution (and much better than the answers provided in the "duplicate" question, in regards to their relevance to my question).
Here is the example using magrittr package:
library(magrittr)
x = c('2015-12-12','2015-12-13','2015-12-14')
df = data.frame(x)
df$x %<>% as.Date

Approaches to preserving object's attributes during extract/replace operations

Recently I encountered the following problem in my R code. In a function, accepting a data frame as an argument, I needed to add (or replace, if it exists) a column with data calculated based on values of the data frame's original column. I wrote the code, but the testing revealed that data frame extract/replace operations, which I've used, resulted in a loss of the object's special (user-defined) attributes.
After realizing that and confirming that behavior by reading R documentation (http://stat.ethz.ch/R-manual/R-patched/library/base/html/Extract.html), I decided to solve the problem very simply - by saving the attributes before the extract/replace operations and restoring them thereafter:
myTransformationFunction <- function (data) {
# save object's attributes
attrs <- attributes(data)
<data frame transformations; involves extract/replace operations on `data`>
# restore the attributes
attributes(data) <- attrs
return (data)
}
This approach worked. However, accidentally, I ran across another piece of R documentation (http://stat.ethz.ch/R-manual/R-patched/library/base/html/Extract.data.frame.html), which offers IMHO an interesting (and, potentially, a more generic?) alternative approach to solving the same problem:
## keeping special attributes: use a class with a
## "as.data.frame" and "[" method:
as.data.frame.avector <- as.data.frame.vector
`[.avector` <- function(x,i,...) {
r <- NextMethod("[")
mostattributes(r) <- attributes(x)
r
}
d <- data.frame(i = 0:7, f = gl(2,4),
u = structure(11:18, unit = "kg", class = "avector"))
str(d[2:4, -1]) # 'u' keeps its "unit"
I would really appreciate if people here could help by:
Comparing the two above-mentioned approaches, if they are comparable (I realize that the second approach as defined is for data frames, but I suspect it can be generalized to any object);
Explaining the syntax and meaning in the function definition in the second approach, especially as.data.frame.avector, as well as what is the purpose of the line as.data.frame.avector <- as.data.frame.vector.
I'm answering my own question, since I have just found an SO question (How to delete a row from a data.frame without losing the attributes), answers to which cover most of my questions posed above. However, additional explanations (for R beginners) for the second approach would still be appreciated.
UPDATE:
Another solution to this problem has been proposed in an answer to the following SO question: indexing operation removes attributes. Personally, however, I better like the approach, based on creating a new class, as it's IMHO semantically cleaner.

Why is it not possible to assign contrasts using with() or transform() in R?

I've been trying to learn more about environments in R. Through reading, it seemed that I should be able to use functions like with() and transform() to modify variables in a data.frame as if I was operating within that object's environment. So, I thought the following might work:
X <- expand.grid(
Cond=c("baseline","perceptual","semantic"),
Age=c("child","adult"),
Gender=c("male","female")
)
Z <- transform(X,
contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4,
contrasts(Age) <- cbind(c(-1,1)/2),
contrasts(Gender) <- cbind(c(-1,1)/2)
)
str(Z)
contrasts(Z$Cond)
But it does not. I was hoping someone could explain why. Of course, I understand that contrasts(X$Cond) <- ... would work, but I'm curious about why this does not.
In fact, this does not work either [EDIT: false, this does work. I tried this quickly before posting originally and did something wrong]:
attach(X)
contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4
contrasts(Age) <- cbind(c(-1,1)/2)
contrasts(Gender) <- cbind(c(-1,1)/2)
detach(X)
I apologize if this is a "RTFM" sort of thing... it's not that I haven't looked. I just don't understand. Thank you!
[EDIT: Thank you joran---within() instead of with() or transform() does the trick! The following syntax worked.]
Z <- within(X, {
contrasts(Cond) <- ...
contrasts(Age) <- ...
contrasts(Gender) <- ...
}
)
transform is definitely the wrong tool, I think. And you don't want with, you probably want within, in order to return the entire object:
X <- within(X,{contrasts(Cond) <- cbind(c(1,0,-1)/2, c(1,-2,1))/4
contrasts(Age) <- cbind(c(-1,1)/2)
contrasts(Gender) <- cbind(c(-1,1)/2)})
The only tricky part here is to remember the curly braces to enclose multiple lines in a single expression.
Your last example, using attach, works just fine for me.
transform is only set up to evaluate expressions of the form tag = value, and because of the way it evaluates those expressions, it isn't really set up to modify attributes of a column. It is more intended for direct modifications to the columns themselves. (Scaling, taking the log, etc.)
The difference between with and within is nicely summed up by the Value section of ?within:
Value For with, the value of the evaluated expr. For within, the modified object.
So with only returns the result of the expression. within is for modifying an object and returning the whole thing.
While I agree with #Jornan that within is the best strategy here, I will point out it is possible to use transform you just need to do so in a different way
Z <- transform(X,
Cond = `contrasts<-`(Cond, value=cbind(c(1,0,-1)/2, c(1,-2,1))/4),
Age = `contrasts<-`(Age, value=cbind(c(-1,1)/2)),
Gender= `contrasts<-`(Gender, value=cbind(c(-1,1)/2))
)
Here we are explicitly calling the magic function that is used when you run contrasts(a)=b. This actually returns a value that can be used with the a=b format that transform expects. And of course it leaves X unchanged.
The within solution looks much cleaner of course.

Resources