Helen
Helen

Reputation: 617

R: make many new vectors based on old ones in dataframe

I have a dataframe like this:

test<-data.frame(year=c(1,2,3),cyl_ring=c(4,3,2),gear_ring=c(1,1,1),wheel_ring=c(1,2,2))#correct typo:change `,` to `=`

I wish to make a new dataset "test2" that contains test and for every column in test that has a name ending with "ring" I wish to make new columns where I change their name to same name with another postfix, say "rang", and multiply by 0.5

new data:

 test<-data.frame(year=c(1,2,3),cyl_ring=c(4,3,2),gear_ring=c(1,1,1),wheel_ring=c(1,2,2),cyl_rang=c(2,1.5,1),gear_rang=c(0.5,0.5,0.5),wheel_rang=c(0.5,1,1))

Upvotes: 0

Views: 45

Answers (2)

Yifu Yan
Yifu Yan

Reputation: 6116

A dplyr way to do it:

library(dplyr)
library(stringr)
test<-data.frame(year=c(1,2,3),cyl_ring=c(4,3,2),gear_ring=c(1,1,1),wheel_ring=c(1,2,2))


test %>%
    mutate_at(vars(ends_with("ring")),funs("new" = . * 0.5)) %>% #dplyr can also add suffix to variable name while using this syntax    
    rename_at(vars(ends_with("ring_new")),~str_replace(.x,"ring_new","rang"))

The only problem is that I don't know how dplyr can mutate and rename (not just adding the suffix, but change variable name instead) multiple variables at the same time. So I need two lines to complete it.

Result 1

> test %>%
    +     mutate_at(vars(ends_with("ring")),funs("new" = . * 0.5))
year cyl_ring gear_ring wheel_ring cyl_ring_new gear_ring_new wheel_ring_new
1    1        4         1          1          2.0           0.5            0.5
2    2        3         1          2          1.5           0.5            1.0
3    3        2         1          2          1.0           0.5            1.0

Result 2

> test %>%
    +     mutate_at(vars(ends_with("ring")),funs("new" = . * 0.5)) %>%
    +     rename_at(vars(ends_with("ring_new")),~str_replace(.x,"ring_new","rang"))
year cyl_ring gear_ring wheel_ring cyl_rang gear_rang wheel_rang
1    1        4         1          1      2.0       0.5        0.5
2    2        3         1          2      1.5       0.5        1.0
3    3        2         1          2      1.0       0.5        1.0

Upvotes: 1

Helen
Helen

Reputation: 617

My own solution so far:

tmp=test[grep("^.*ring",colnames(test),perl=TRUE)]*0.5
colnames(tmp) <- gsub("(^.*)ring","\\1rang",colnames(tmp))
test2<-cbind(test,tmp)

Upvotes: 0

Related Questions