1

Suppose i have the following Db:

db<-data.frame(para=c(round(rnorm(20,10,10),0)),sal1=c(rnorm(20,100,7)),sal2=c(rnorm(20,100,7)),sal3=c(rnorm(10,100,7)),sal4=rep(c("a","b"),5))

para      sal1      sal2      sal3     sal4
1    13 104.73988  96.53538 107.03285    a
2     1  94.54826  88.79930 101.17248    b
3    26 102.36344  94.83702  91.11708    a
4    13  99.32913  95.90670  90.49470    b

Basically what i want:

paste(db$sal1,db$sal2,db$sal3, sep="-")
para   sal1   sal2   sal3     sal4               newcol
1     8 105.11 101.38 100.01    a 105.11-101.38-100.01
2     2 109.55  88.98 104.12    b  109.55-88.98-104.12
3    25 100.12 103.84 102.43    a 100.12-103.84-102.43
4    15 105.22  90.95 100.67    b  105.22-90.95-100.67
5    21  97.57  97.78 103.89    a   97.57-97.78-103.89
6    -1 101.88 100.22  88.21    b  101.88-100.22-88.21
7    12 104.20  95.26  93.72    a    104.2-95.26-93.72
8    16 106.25 100.70  94.95    b   106.25-100.7-94.95
9    24 101.36  97.91  99.67    a   101.36-97.91-99.67

Actually the way i want:

colnam<-c("sal1","sal2","sal3")
colnameful<-paste0("db$",colnam)

paste using variable colnameful

Something like below i tried:

paste(colnameful, sep="-") # Useless

Please suggest, Thanks in advance.

Abhijeet Arora
  • 237
  • 3
  • 13

2 Answers2

4

Maybe something like:

colnam<-c("sal1","sal2","sal3")
db[[paste(colnam,collapse = "-")]] <- with(db,paste(sal1,sal2,sal3,sep = "-"))

...though you may find that you want to round the sal1, etc values before pasting them together.

If you only have the columns in a character vector you could try this instead of the with() piece:

do.call(paste,c(db[,colnam],sep = "-"))
joran
  • 169,992
  • 32
  • 429
  • 468
  • Still you need to write `with(db,paste(sal1,sal2,sal3,sep = "-"))` i have this in object only there are 100s of columns in the actual db. – Abhijeet Arora Sep 20 '16 at 18:21
  • 2
    @AbhijeetArora Probably you could do `do.call(paste,c(db[,colnam],sep = "-"))` if you needed to. – joran Sep 20 '16 at 18:30
  • Perfect this is exactly what i wanted! .. Thanks a lot.. could you edit this in the Answer, so that i can accept the answer? – Abhijeet Arora Sep 20 '16 at 18:59
0

EDIT:

Thanks to @joran and @Gregor (from the comments) who helped me understand that it is not good practice to use eval(parse(text = '')) . Also the function which I wrote was unnecessarily over complicated. So just found out a simple solution with only one loop (apply)

apply(db[colnam], 1, paste, collapse = "-") 

Original Answer :

Based on the output showed , it seems you want to paste sal1 , sal2 and sal3 together but using colnam

colnam<-c("sal1","sal2","sal3")

You can use eval(parse( combination in sapply to get the values and then apply row-wise computation to paste the columns together

apply(sapply(paste0("db$",colnam), function(x) eval(parse(text = x))), 1,
                            function(x) paste(x, collapse = "-"))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • 2
    FYI, pretty much anything recommending `eval(parse(text = ...))` will be met with down votes, as it is widely and strongly discouraged. – joran Sep 20 '16 at 18:24
  • No. Not you! Just trying to figure out what can be wrong here. – Ronak Shah Sep 20 '16 at 18:25
  • @joran and the reason why is it discouraged? – Ronak Shah Sep 20 '16 at 18:25
  • Also, applying the `paste` row-wise seems needlessly inefficient. Perhaps I'm misunderstanding (I'm not sure I understand what result OP is after), but it seems like it's deliberately taking a vectorized function and un-vectorizing it. – Gregor Thomas Sep 20 '16 at 18:26
  • For some discussion, you could start [here](http://stackoverflow.com/q/13649979/324364). – joran Sep 20 '16 at 18:30
  • Yes, after seeing joran's `do.call` solution in the comments, you're taking a vectorized funciton, `paste`, and wrapping it in two for loops (1 `sapply` and 1 `apply`) to avoid using `paste`'s built-in vectorization. – Gregor Thomas Sep 20 '16 at 18:34