I'm trying to learn about loops and I currently have a long list of data frames and I need to go inside a bunch of these data frames and rename some variables. I have a function, but I’m struggling to construct a smart way to loop thru my list (the real list is much longer than in the example below) and at the same time apply varying suffixes prefixes hen renaming.
Hopefully my working example below will illustrate the situation. I imagine I can build the last part into two loops, but I can't seem to figure out how I write to the data frame inside the list inside a loop.
Any help would be appreciated!
data(mtcars)
mtcarsList <- list(mtcars1 = mtcars, mtcars2 = mtcars,
mtcarsA = mtcars, mtcars = mtcars )
# function I use to renames a specific number of variables
baRadd <- function(df, vector, suffix){
names(df) <- ifelse(names(df) %in% vector,names(df),
paste(suffix, names(df), sep = "."))
return(df)}
foo <- c("mpg", "cyl", "disp")
suffix1 <- "bar"
suffix2 <- "barBAR"
suffix3 <- "barBARbar"
mtcarsList$mtcars1 <- baRadd(mtcarsList$mtcars1, foo, suffix1)
mtcarsList$mtcars2 <- baRadd(mtcarsList$mtcars2, foo, suffix2)
mtcarsList$mtcarsA <- baRadd(mtcarsList$mtcarsA, foo, suffix3)
names(mtcarsList$mtcars1)
# [1] "mpg" "cyl" "disp" "bar.hp" "bar.drat" "bar.wt"
# [7] "bar.qsec" "bar.vs" "bar.am" "bar.gear" "bar.carb"
names(mtcarsList$mtcars2)
# [1] "mpg" "cyl" "disp" "barBAR.hp" "barBAR.drat"
# [6] "barBAR.wt" "barBAR.qsec" "barBAR.vs" "barBAR.am" "barBAR.gear"
# [11] "barBAR.carb"
names(mtcarsList$mtcarsA)
# [1] "mpg" "cyl" "disp" "barBARbar.hp"
# [5] "barBARbar.drat" "barBARbar.wt" "barBARbar.qsec" "barBARbar.vs"
# [9] "barBARbar.am" "barBARbar.gear" "barBARbar.carb"
names(mtcarsList$mtcars)
# [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear"
# [11] "carb"
Update,
Based on DWin's response below I write this scrip that solves my issue,
# rm(list = ls(all = TRUE)) ## Clear workspace
data(mtcars)
mtcarsList <- list(mtcars1 = mtcars, mtcars2 = mtcars,
mtcarsA = mtcars, mtcars = mtcars)
## function I use to renames a specific number of variables
baRadd <- function(df, vector, suffix){
names(df) <- ifelse(names(df) %in% vector,names(df),
paste(suffix, names(df), sep = "."))
return(df)}
suffixes <- c('A', 'B', 'C') # suffixes to be added to the three dfTO
whatNOTtoRename <- c("mpg", "cyl", "disp")
# variables within the data frame I do not want to renames
dfTO <- c('mtcars1','mtcars2','mtcarsA')
# the specific data frames I need to rename
# str(mtcarsList)
mtcarsList[ names( mtcarsList[dfTO]) ] <-
mapply(baRadd, df=mtcarsList[dfTO],
suffix= suffixes,
MoreArgs=list(vector=whatNOTtoRename) , SIMPLIFY=FALSE)
str(mtcarsList)
Looks as though mapply can do this task:
> newList <- mapply(baRadd, df=mtcarsList[1:3], suffix= c(suffix1, suffix2, suffix3), MoreArgs=list(vector=foo) , SIMPLIFY=FALSE)
> str(newList)
List of 3
$ mtcars1:'data.frame': 32 obs. of 11 variables:
..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
..$ cyl : num [1:32] 6 6 4 6 8 6 8 4 4 6 ...
..$ disp : num [1:32] 160 160 108 258 360 ...
..$ bar.hp : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
..$ bar.drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
..$ bar.wt : num [1:32] 2.62 2.88 2.32 3.21 3.44 ...
..$ bar.qsec: num [1:32] 16.5 17 18.6 19.4 17 ...
..$ bar.vs : num [1:32] 0 0 1 1 0 1 0 1 1 1 ...
..$ bar.am : num [1:32] 1 1 1 0 0 0 0 0 0 0 ...
..$ bar.gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
..$ bar.carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ...
$ mtcars2:'data.frame': 32 obs. of 11 variables:
..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
..$ cyl : num [1:32] 6 6 4 6 8 6 8 4 4 6 ...
..$ disp : num [1:32] 160 160 108 258 360 ...
..$ barBAR.hp : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
..$ barBAR.drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
..$ barBAR.wt : num [1:32] 2.62 2.88 2.32 3.21 3.44 ...
..$ barBAR.qsec: num [1:32] 16.5 17 18.6 19.4 17 ...
..$ barBAR.vs : num [1:32] 0 0 1 1 0 1 0 1 1 1 ...
..$ barBAR.am : num [1:32] 1 1 1 0 0 0 0 0 0 0 ...
..$ barBAR.gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
..$ barBAR.carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ...
$ mtcarsA:'data.frame': 32 obs. of 11 variables:
..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
..$ cyl : num [1:32] 6 6 4 6 8 6 8 4 4 6 ...
..$ disp : num [1:32] 160 160 108 258 360 ...
..$ barBARbar.hp : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
..$ barBARbar.drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
..$ barBARbar.wt : num [1:32] 2.62 2.88 2.32 3.21 3.44 ...
..$ barBARbar.qsec: num [1:32] 16.5 17 18.6 19.4 17 ...
..$ barBARbar.vs : num [1:32] 0 0 1 1 0 1 0 1 1 1 ...
..$ barBARbar.am : num [1:32] 1 1 1 0 0 0 0 0 0 0 ...
..$ barBARbar.gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
..$ barBARbar.carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ...
If you wanted to assign that result to mtcarsList[1:3], that too should be possible.
To your comment: this succeeds ....
mtcarsList[ names( mtcarsList[1:3]) ] <-
mapply(baRadd, df=mtcarsList[1:3],
suffix= c(suffix1, suffix2, suffix3),
MoreArgs=list(vector=foo) , SIMPLIFY=FALSE)
# omitted output of str(mtcarsList) ....
Related
I have a table of data made in excel that i converted to a txt file.
The command I'm using will only let me run it if I have only two columns. I transposed my data into columns but now I need to somehow split it all up so every column 2 to column 189 is a different table with column 1 staying the same in all.
Is it possible to then run the exact same set of commands over and over again for the 188 tables created and save the resulting data into a separate file (or better yet substitute some of the obtained values into an equation).
Sorry if the question is too long or ridiculously easy - I'm a complete newbie to anything beyond basic analysis.
Happy to try and learn other programs if it will solve my problem.
You can do the following in base R (I use the built-in mtcars data.frame as an example)
df <- mtcars
lst <- apply(rbind(1, 2:ncol(df)), 2, function(idx) df[, idx])
This returns a list of data.frames with columns (1,2), (1,3), (1,4) and so on, of the original data.frame.
str(lst)
#List of 10
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg: num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ cyl: num [1:32] 6 6 4 6 8 6 8 4 4 6 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ disp: num [1:32] 160 160 108 258 360 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg: num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ hp : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg: num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ wt : num [1:32] 2.62 2.88 2.32 3.21 3.44 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ qsec: num [1:32] 16.5 17 18.6 19.4 17 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg: num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ vs : num [1:32] 0 0 1 1 0 1 0 1 1 1 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg: num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ am : num [1:32] 1 1 1 0 0 0 0 0 0 0 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
# $ :'data.frame': 32 obs. of 2 variables:
# ..$ mpg : num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
# ..$ carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ...
It's not easy to operate on the list of data.frames using a function from the *apply family.
To generate the basic combinations, you could use Map:
Map(cbind, df[1], df[-1])
To apply a function to each combination you would need to edit the function a bit:
Map(function(a,b) fun(cbind(a,b)), df[1], df[-1])
Or add another level of looping with lapply if you want to keep the code compact.
lapply(Map(cbind, df[1], df[-1]), fun)
names <- names(mtcars)
str(mtcars[names[1]]) # shows the str for mpg data frame
I would like to select everything EXCEPT names[1] which in this example is mpg.
Tried:
str(mtcars[!names[1]])
Error in !names[1] : invalid argument type
Also tried
str(mtcars[-names[1]])
Error in -names[1] : invalid argument to unary operator
How can I select mtcars minus names[1] feature using square braces syntax?
str(mtcars[!names %in% names[1]])
'data.frame': 32 obs. of 10 variables:
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
If you want to use numerical indexing for selection, you can just use a - in front of that to do the reverse.
str(mtcars[names[1]]) # shows the str for mpg data frame
'data.frame': 32 obs. of 1 variable:
$ mpg: num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
str(mtcars[names[-1]])
'data.frame': 32 obs. of 10 variables:
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
I'm working on a package that relies on adding a class and attributes to a data frame, and would like to be able to use dplyr verbs with it.
The only trouble is they seem to strip away the classes and attributes that I've added to my data frames.
Example
class(mtcars) <- c("new_class", class(mtcars))
attr(mtcars, "foo") <- "bar"
Examining the structure shows that mtcars now includes the new class and attributes
> mtcars %>% str
Classes ‘new_class’, ‘new_class’ and 'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
- attr(*, "foo")= chr "bar"
But when I use filter, it seems to lose the classes and attributes.
> mtcars %>% filter(cyl == 8) %>% str
'data.frame': 14 obs. of 11 variables:
$ mpg : num 18.7 14.3 16.4 17.3 15.2 10.4 10.4 14.7 15.5 15.2 ...
$ cyl : num 8 8 8 8 8 8 8 8 8 8 ...
$ disp: num 360 360 276 276 276 ...
$ hp : num 175 245 180 180 180 205 215 230 150 150 ...
$ drat: num 3.15 3.21 3.07 3.07 3.07 2.93 3 3.23 2.76 3.15 ...
$ wt : num 3.44 3.57 4.07 3.73 3.78 ...
$ qsec: num 17 15.8 17.4 17.6 18 ...
$ vs : num 0 0 0 0 0 0 0 0 0 0 ...
$ am : num 0 0 0 0 0 0 0 0 0 0 ...
$ gear: num 3 3 3 3 3 3 3 3 3 3 ...
$ carb: num 2 4 3 3 3 4 4 4 2 2 ...
Is that behaviour expected?
What can I do to work around it?
filter calls filter_, which uses the method for a data.frame (because there is no filter method for new_class. filter_.data.frame then uses calls the filter method for a tbl_df and uses as.data.frame to return a data.frame.
dplyr:::filter_.data.frame
## function (.data, ..., .dots)
## {
## dots <- lazyeval::all_dots(.dots, ..., all_named = TRUE)
## as.data.frame(filter_(tbl_df(.data), .dots = dots))
## }
## <environment: namespace:dplyr>
The coercion to tbl_df removes the extra class, but keeps the attribute foo.
mtcars %>% tbl_df %>% str
The filtering seems to loose the attribute foo.
mtcars %>% tbl_df %>% filter(cyl == 8) %>% str
I saw some similar questions here, but none exactly like mine - or if they were the same, I didn't recognize it, as a rank newbie to programming in R (I've programmed in lots of other languages, but not R!)
I have an input dataset from a csv file, that I convert with read.csv. The dataset may or may not, have two groups in it. I found I could split the groups as follows:
datalist <- split(mydata, mydata$group)
but then the list I get back does not play nice with ggplot2 (I get an error that it cannot plot a list variable - although the list variable, if I print it to the console, shows the split data subset?). OK, fine. But if I then do
data = as.data.frame(datalist[1])
And feed that to ggplot2, as.data.frame mangles my column names, and so I lose the name of the variable I want to plot. Augh!
What I ideally want, is to split my input data as read by read.csv, into two separate variables (data frames, I take it?) that ggplot2 can recognize as valid data sets. Actually, I want to overlay them as histograms on the same plot.
There HAS to be an easy way to do this, but I'm not gettin' it? Advice or pointers welcome.
If you just want a single index value then using subset might be easier (at least for interactive use.)
p <- qplot(value, # assuming there is a column named "value"
data = subset(mydata, group==mydata$group[1]),
colour = "cyan")
The result of split(mydata, mydata$group) is a list of data.frames. There is a difference in the [ and [[ notation: [ subsets the list where [[ extracts from the list. So datalist[1] is a list of length 1 consisting of just the first data.frame. datalist[[1]] is the data.frame which is in the first position. Since ggplot (and qplot) expects a data.frame, you need the second (double bracket) version as #Alex mentioned in the comment. I don't know why you got the error you saw and can't diagnosis it without a complete example. Using a different data set (mtcars), I don't see it.
datalist <- split(mtcars, mtcars$am)
ggplot(datalist[[1]], aes(x=wt, y=mpg)) + geom_point()
qplot(wt, data=datalist[[1]], colour="cyan")
(I'm guessing you wanted colour=I("cyan"), but that's an unrelated issue.)
The difference in the subsetting/extraction operators can be seen here:
> str(datalist)
List of 2
$ 0:'data.frame': 19 obs. of 11 variables:
..$ mpg : num [1:19] 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 ...
..$ cyl : num [1:19] 6 8 6 8 4 4 6 6 8 8 ...
..$ disp: num [1:19] 258 360 225 360 147 ...
..$ hp : num [1:19] 110 175 105 245 62 95 123 123 180 180 ...
..$ drat: num [1:19] 3.08 3.15 2.76 3.21 3.69 3.92 3.92 3.92 3.07 3.07 ...
..$ wt : num [1:19] 3.21 3.44 3.46 3.57 3.19 ...
..$ qsec: num [1:19] 19.4 17 20.2 15.8 20 ...
..$ vs : num [1:19] 1 0 1 0 1 1 1 1 0 0 ...
..$ am : num [1:19] 0 0 0 0 0 0 0 0 0 0 ...
..$ gear: num [1:19] 3 3 3 3 4 4 4 4 3 3 ...
..$ carb: num [1:19] 1 2 1 4 2 2 4 4 3 3 ...
$ 1:'data.frame': 13 obs. of 11 variables:
..$ mpg : num [1:13] 21 21 22.8 32.4 30.4 33.9 27.3 26 30.4 15.8 ...
..$ cyl : num [1:13] 6 6 4 4 4 4 4 4 4 8 ...
..$ disp: num [1:13] 160 160 108 78.7 75.7 ...
..$ hp : num [1:13] 110 110 93 66 52 65 66 91 113 264 ...
..$ drat: num [1:13] 3.9 3.9 3.85 4.08 4.93 4.22 4.08 4.43 3.77 4.22 ...
..$ wt : num [1:13] 2.62 2.88 2.32 2.2 1.61 ...
..$ qsec: num [1:13] 16.5 17 18.6 19.5 18.5 ...
..$ vs : num [1:13] 0 0 1 1 1 1 1 0 1 0 ...
..$ am : num [1:13] 1 1 1 1 1 1 1 1 1 1 ...
..$ gear: num [1:13] 4 4 4 4 4 4 4 5 5 5 ...
..$ carb: num [1:13] 4 4 1 1 2 1 1 2 2 4 ...
> str(datalist[1])
List of 1
$ 0:'data.frame': 19 obs. of 11 variables:
..$ mpg : num [1:19] 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 ...
..$ cyl : num [1:19] 6 8 6 8 4 4 6 6 8 8 ...
..$ disp: num [1:19] 258 360 225 360 147 ...
..$ hp : num [1:19] 110 175 105 245 62 95 123 123 180 180 ...
..$ drat: num [1:19] 3.08 3.15 2.76 3.21 3.69 3.92 3.92 3.92 3.07 3.07 ...
..$ wt : num [1:19] 3.21 3.44 3.46 3.57 3.19 ...
..$ qsec: num [1:19] 19.4 17 20.2 15.8 20 ...
..$ vs : num [1:19] 1 0 1 0 1 1 1 1 0 0 ...
..$ am : num [1:19] 0 0 0 0 0 0 0 0 0 0 ...
..$ gear: num [1:19] 3 3 3 3 4 4 4 4 3 3 ...
..$ carb: num [1:19] 1 2 1 4 2 2 4 4 3 3 ...
> str(datalist[[1]])
'data.frame': 19 obs. of 11 variables:
$ mpg : num 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 ...
$ cyl : num 6 8 6 8 4 4 6 6 8 8 ...
$ disp: num 258 360 225 360 147 ...
$ hp : num 110 175 105 245 62 95 123 123 180 180 ...
$ drat: num 3.08 3.15 2.76 3.21 3.69 3.92 3.92 3.92 3.07 3.07 ...
$ wt : num 3.21 3.44 3.46 3.57 3.19 ...
$ qsec: num 19.4 17 20.2 15.8 20 ...
$ vs : num 1 0 1 0 1 1 1 1 0 0 ...
$ am : num 0 0 0 0 0 0 0 0 0 0 ...
$ gear: num 3 3 3 3 4 4 4 4 3 3 ...
$ carb: num 1 2 1 4 2 2 4 4 3 3 ...
I'm renaming the majority of the variables in a data frame and I'm not really impressed with my method.
Therefore, does anyone on SO have a smarter or faster way then the one presented below using only base?
data(mtcars)
# head(mtcars)
temp.mtcars <- mtcars
names(temp.mtcars) <- c((x <- c("mpg", "cyl", "disp")),
gsub('^', "baR.", setdiff(names (mtcars),x)))
str(temp.mtcars)
'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp : num 160 160 108 258 360 ...
$ baR.hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ baR.drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ baR.wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ baR.qsec: num 16.5 17 18.6 19.4 17 ...
$ baR.vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ baR.am : num 1 1 1 0 0 0 0 0 0 0 ...
$ baR.gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ baR.carb: num 4 4 1 1 2 1 4 2 2 4 ...
Edited for answer using base R only
The package plyr has a convenient function rename() that does what you ask. Your modified question specifies using base R only. One easy way of doing this is to simply copy the code from plyr::rename and create your own function.
rename <- function (x, replace) {
old_names <- names(x)
new_names <- unname(replace)[match(old_names, names(replace))]
setNames(x, ifelse(is.na(new_names), old_names, new_names))
}
The function rename takes an argument that is a named vector, where the elements of the vectors are the new names, and the names of the vector are the existing names. There are many ways to construct such a named vector. In the example below I simply use structure.
x <- c("mpg", "disp", "wt")
some.names <- structure(paste0("baR.", x), names=x)
some.names
mpg disp wt
"baR.mpg" "baR.disp" "baR.wt"
Now you are ready to rename:
mtcars <- rename(mtcars, replace=some.names)
The results:
'data.frame': 32 obs. of 11 variables:
$ baR.mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ baR.disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat : num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ baR.wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec : num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear : num 4 4 4 3 3 3 3 4 4 4 ...
$ carb : num 4 4 1 1 2 1 4 2 2 4 ...
I would use ifelse:
names(temp.mtcars) <- ifelse(names(mtcars) %in% c("mpg", "cyl", "disp"),
names(mtcars),
paste("bar", names(mtcars), sep = "."))
Nearly the same but without plyr:
data(mtcars)
temp.mtcars <- mtcars
carNames <- names(temp.mtcars)
modifyNames <- !(carNames %in% c("mpg", "cyl", "disp"))
names(temp.mtcars)[modifyNames] <- paste("baR.", carNames[modifyNames], sep="")
Output:
str(temp.mtcars)
'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp : num 160 160 108 258 360 ...
$ baR.hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ baR.drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ baR.wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ baR.qsec: num 16.5 17 18.6 19.4 17 ...
$ baR.vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ baR.am : num 1 1 1 0 0 0 0 0 0 0 ...
$ baR.gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ baR.carb: num 4 4 1 1 2 1 4 2 2 4 ...
You could use the rename.vars function in the gdata package.
It works well when you only want to replace a subset of variable names and where the order of your vector of names is not the same as the order of names in the data.frame.
Adapted from the help file:
library(gdata)
data <- data.frame(x=1:10,y=1:10,z=1:10)
names(data)
data <- rename.vars(data, from=c("z","y"), to=c("Z","Y"))
names(data)
Converts data.frame names:
[1] "x" "y" "z"
to
[1] "x" "Y" "Z"
I.e., Note how this handles the subsetting and the fact that string of names are not in the same order as the names in the data.frame.
names(df)[match(
c('old_var1','old_var2'),
names(df)
)]=c('new_var1', 'new_var2')