Not / negative column select using braces syntax - r

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 ...

Related

append n identical dataframes with id [duplicate]

This question already has answers here:
Repeat rows of a data.frame N times
(10 answers)
Closed 4 years ago.
I want to append n identical data frames to each other. This works if n=2:
> d = data.frame(a=1:2)
> dplyr::bind_rows(d,d, .id="id")
# id a
# 1 1
# 1 2
# 2 1
# 2 2
But I don't know how to extend this to larger values of n, without manually typing something like dplyr::bind_rows(d,d,d .id="id") for n = 3. Is there some smart way to programatically feed a list of d with length=n to the bind_rows command? This doesn't work: dplyr::bind_rows(rep(d,3), .id="id").
Also - is there a data.table solution?
Here's a solution using data.table::rbindlist():
library(data.table)
l <- list(mtcars, mtcars*2, mtcars*3)
DATA
# Check l
> str(l)
List of 3
$ :'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 ...
..$ hp : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
..$ drat: num [1:32] 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
..$ wt : num [1:32] 2.62 2.88 2.32 3.21 3.44 ...
..$ qsec: num [1:32] 16.5 17 18.6 19.4 17 ...
..$ vs : num [1:32] 0 0 1 1 0 1 0 1 1 1 ...
..$ am : num [1:32] 1 1 1 0 0 0 0 0 0 0 ...
..$ gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
..$ carb: num [1:32] 4 4 1 1 2 1 4 2 2 4 ...
$ :'data.frame': 32 obs. of 11 variables:
..$ mpg : num [1:32] 42 42 45.6 42.8 37.4 36.2 28.6 48.8 45.6 38.4 ...
..$ cyl : num [1:32] 12 12 8 12 16 12 16 8 8 12 ...
..$ disp: num [1:32] 320 320 216 516 720 ...
..$ hp : num [1:32] 220 220 186 220 350 210 490 124 190 246 ...
..$ drat: num [1:32] 7.8 7.8 7.7 6.16 6.3 5.52 6.42 7.38 7.84 7.84 ...
..$ wt : num [1:32] 5.24 5.75 4.64 6.43 6.88 6.92 7.14 6.38 6.3 6.88 ...
..$ qsec: num [1:32] 32.9 34 37.2 38.9 34 ...
..$ vs : num [1:32] 0 0 2 2 0 2 0 2 2 2 ...
..$ am : num [1:32] 2 2 2 0 0 0 0 0 0 0 ...
..$ gear: num [1:32] 8 8 8 6 6 6 6 8 8 8 ...
..$ carb: num [1:32] 8 8 2 2 4 2 8 4 4 8 ...
$ :'data.frame': 32 obs. of 11 variables:
..$ mpg : num [1:32] 63 63 68.4 64.2 56.1 54.3 42.9 73.2 68.4 57.6 ...
..$ cyl : num [1:32] 18 18 12 18 24 18 24 12 12 18 ...
..$ disp: num [1:32] 480 480 324 774 1080 ...
..$ hp : num [1:32] 330 330 279 330 525 315 735 186 285 369 ...
..$ drat: num [1:32] 11.7 11.7 11.55 9.24 9.45 ...
..$ wt : num [1:32] 7.86 8.62 6.96 9.64 10.32 ...
..$ qsec: num [1:32] 49.4 51.1 55.8 58.3 51.1 ...
..$ vs : num [1:32] 0 0 3 3 0 3 0 3 3 3 ...
..$ am : num [1:32] 3 3 3 0 0 0 0 0 0 0 ...
..$ gear: num [1:32] 12 12 12 9 9 9 9 12 12 12 ...
..$ carb: num [1:32] 12 12 3 3 6 3 12 6 6 12 ...
CODE & OUTPUT
dat <- rbindlist(l, use.names = T, fill = T)
# Verify if data looks like what we want
> str(dat)
Classes ‘data.table’ and 'data.frame': 96 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(*, ".internal.selfref")=<externalptr>

str() prints first no matter the order in R

I am writing a function that would give the dim() and str() of a given dataset.
JustfunFun <- function(.csv) {
csv <- read.csv(.csv)
dimVal <- dim(csv)
print("The dimension of the dataset is:")
strVal <- str(csv)
print("The structute of the dataset is:")
headVal <- head(csv)
return(list(dimVal, strVal, headVal))
}
Ideally, the output must have the dimension first, the structure second and then the head of dataset.
But the output is as follows:
> JustfunFun("tips.csv")
[1] "The dimension of the dataset is:"
'data.frame': 244 obs. of 8 variables:
$ obs : int 1 2 3 4 5 6 7 8 9 10 ...
$ totbill: num 17 10.3 21 23.7 24.6 ...
$ tip : num 1.01 1.66 3.5 3.31 3.61 4.71 2 3.12 1.96 3.23 ...
$ sex : Factor w/ 2 levels "F","M": 1 2 2 2 1 2 2 2 2 2 ...
$ smoker : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
$ day : Factor w/ 4 levels "Fri","Sat","Sun",..: 3 3 3 3 3 3 3 3 3 3 ...
$ time : Factor w/ 2 levels "Day","Night": 2 2 2 2 2 2 2 2 2 2 ...
$ size : int 2 3 3 2 4 4 2 4 2 2 ...
[1] "The structute of the dataset is:"
[1] "The head of the dataset is:"
[[1]]
[1] 244 8
[[2]]
NULL
[[3]]
obs totbill tip sex smoker day time size
1 1 16.99 1.01 F No Sun Night 2
2 2 10.34 1.66 M No Sun Night 3
3 3 21.01 3.50 M No Sun Night 3
4 4 23.68 3.31 M No Sun Night 2
5 5 24.59 3.61 F No Sun Night 4
6 6 25.29 4.71 M No Sun Night 4
>
How do I tackle this problem?
str, like print does not return anything. You can see the last line of utils:::str.default. The easiest way to see this is try to nest a str ( ie. str(str(mtcars)) ).
This function should print the way you want, AND store the data.
JustfunFun <- function(.csv) {
csv <- read.csv(.csv)
dimVal <- dim(csv)
print("The dimension of the dataset is:")
print(dimVal)
print("The structute of the dataset is:")
strVal <- utils:::capture.output(str(csv))
print(strVal)
print(head(csv))
return(invisible(list(dimVal, strVal, head(csv))))
}
Example:
write.csv(mtcars, "mtcars.csv", row.names = FALSE)
a <- JustfunFun("mtcars.csv")
Result:
[1] "The dimension of the dataset is:"
[1] 32 11
[1] "The structute of the dataset is:"
[1] "'data.frame':\t32 obs. of 11 variables:"
[2] " $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ..."
[3] " $ cyl : int 6 6 4 6 8 6 8 4 4 6 ..."
[4] " $ disp: num 160 160 108 258 360 ..."
[5] " $ hp : int 110 110 93 110 175 105 245 62 95 123 ..."
[6] " $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ..."
[7] " $ wt : num 2.62 2.88 2.32 3.21 3.44 ..."
[8] " $ qsec: num 16.5 17 18.6 19.4 17 ..."
[9] " $ vs : int 0 0 1 1 0 1 0 1 1 1 ..."
[10] " $ am : int 1 1 1 0 0 0 0 0 0 0 ..."
[11] " $ gear: int 4 4 4 3 3 3 3 4 4 4 ..."
[12] " $ carb: int 4 4 1 1 2 1 4 2 2 4 ..."
mpg cyl disp hp drat wt qsec vs am gear carb
1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
5 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
6 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
str(a)
$ : int [1:2] 32 11
$ : chr [1:12] "'data.frame':\t32 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 : int 6 6 4 6 8 6 8 4 4 6 ..." " $ disp: num 160 160 108 258 360 ..." ...
$ :'data.frame': 6 obs. of 11 variables:
..$ mpg : num [1:6] 21 21 22.8 21.4 18.7 18.1
..$ cyl : int [1:6] 6 6 4 6 8 6
..$ disp: num [1:6] 160 160 108 258 360 225
..$ hp : int [1:6] 110 110 93 110 175 105
..$ drat: num [1:6] 3.9 3.9 3.85 3.08 3.15 2.76
..$ wt : num [1:6] 2.62 2.88 2.32 3.21 3.44 ...
..$ qsec: num [1:6] 16.5 17 18.6 19.4 17 ...
..$ vs : int [1:6] 0 0 1 1 0 1
..$ am : int [1:6] 1 1 1 0 0 0
..$ gear: int [1:6] 4 4 4 3 3 3
..$ carb: int [1:6] 4 4 1 1 2 1
Everything that you have written in your function is correct except the fact that you need to capture the strby command capture.output. So, below is the function that you are looking for:
JustfunFun <- function(.csv) {
csv <- read.csv(.csv)
dimVal <- dim(csv)
strVal <- capture.output(str(csv))
headVal <- head(csv)
return(list("The dimension of the dataset is:" = dimVal,
"The structute of the dataset is:" = strVal,
headVal))
}
Cheers & happy R Coding
If you are only interested in displaying the result without storing it, you could write a function that does not return anything but print the dimensions, the structure and the head of the data. The following code seems to do the trick.
# Simulation of the data
dat <- data.frame(obs=1:100,totbill=round(100*runif(100)),sex=sample(c("F","M"),100,replace=TRUE))
# Function
dim.str.head <- function(dat){
print("The dimension of the dataset is:")
print(dim(dat))
print("The structure of the dataset is:")
print(str(dat))
print("The first observations look like this:")
head(dat)
}
# Try the function
dim.str.head(dat)

dplyr verbs removing custom classes and attributes?

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

Splitting a dataset into two datasets in R (for ggplot2 channeled through Shiny)

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 ...

R: rename subset of variables in data frame

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')

Resources