1

The goal is to have the last argument of the function call to provide the name for the new column to be bound to the original data frame.

Referring to this and this previous question and building upon the minimal working example of the first.

GroupId <-          c(1,1,1,1,2,2,2,3,3)
IndId <-            c(1,1,2,2,3,4,4,5,5)
IndGroupProperty <- c(1,2,1,2,3,3,4,5,6)
PropertyType <-     c(1,2,1,2,2,2,1,2,2)

df <- data.frame(GroupId, IndId, IndGroupProperty, PropertyType)
df

ValidGroupC <-       c(1,1,1,1,0,0,0,0,0)
df <- data.frame(df, ValidGroupC)
df

library(dplyr)
grouptest <- function(object, group, ind, type, new){
groupvar <- deparse(substitute(group)) 
indvar <- deparse(substitute(ind)) 
typevar <- deparse(substitute(type)) 
eval(substitute(
tmp <- object[, c(groupvar, indvar, typevar)] %.%
  group_by(group, ind) %.%
  mutate(type1 = any(type == 1))  %.%
  group_by(group, add = FALSE) %.%
  mutate(tmp2 = all(type1) * 1) %.%
  select(-type1)
  ))
new <- tmp[, 4]                    # this is the relevant part
tmp <- cbind(object, new)          # this is the relevant part
}

df <- grouptest(df, GroupId, IndId, PropertyType, ValidGroup)
df

So most of the code is already a product of the referenced questions. The relevant part for this question is at the end where I take the 4th column of the calculations I made to tmp and put it in an new object, the name of which should be taken from the new argument in the function call, which I then bind to the original data frame.

My question: why is the last column of the final df not named ValidGroup ? I don't get what is wrong - new should be replaced by ValidGroup, but it isn't?

I have tried putting the two lines inside the eval(), which results in Error in cbind(df, ValidGroup) : object 'ValidGroup' not found.

I have tried putting another eval(substitute()) around the two lines, same Error.

I have tried numerous other variations of where to put the lines, using a deparsed newvar, naming the tmp also new, . . .

3 Answers 3

1

You want to change the last two lines highlighted in your function to:

object[, new] <- tmp[, 4]
object

Then, when you call the function specify the new argument as a character string:

> df <- grouptest(df, GroupId, IndId, PropertyType, "ValidGroup")   
> df
  GroupId IndId IndGroupProperty PropertyType ValidGroupC ValidGroup
1       1     1                1            1           1          1
2       1     1                2            2           1          1
3       1     2                1            1           1          1
4       1     2                2            2           1          1
5       2     3                3            2           0          0
6       2     4                3            2           0          0
7       2     4                4            1           0          0
8       3     5                5            2           0          0
9       3     5                6            2           0          0
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, that works! Is it just me or can R syntax sometimes be quirky? To me that looks very similar to what i originally had...
Everything takes practice. In time it will all become clear. :)
0

If the object is always a data.frame, why don't you simply make a new one?

tmp <- data.frame(object, new=tmp[,4])
names(tmp)[4] <- as.character(match.call()$new)
return(tmp)

Edit: Changed code to accept name instead of character for argument new. I still don't think this is a good idea, though. You should at least have an optional argument to switch the second line to just names(tmp)[4] <- new in line with @hadley 's reasoning in this thread.

6 Comments

I don't see your point. That still does not result in the new column to be named correctly?
My bad :-). I added a solution, but I think this may result in the data.frame being rewritten. If it were a data.table, you could use setnames() to change it in place.
This does not work, results in the same Error in grouptest(df, GroupId, IndId, PropertyType, ValidGroup) : object 'ValidGroup' not found
ValidGroup would have to be a character variable. I am not sure there is a way to do it otherwise.
Well I also tried to deparse() the value of new, which should render it a character class string and that didn't work either... :(
|
0

I suspect that you are looking for the assign function:

assign(deparse(substitute(new)), tmp[,4])

So apparently I missunderstood the question. Here's another approach. Instead of using cbind, you can just add a new column to your existing object.

object[, deparse(substitute(new))] <- tmp[,4]
object

1 Comment

Thank you for your reply. How would I got about applying this? By simply adding two more lines at the end of the function I still get the last column named "new". I added the two lines assign(deparse(substitute(new)), tmp[,4]) and tmp between tmp <- cbind(object, new) and }.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.