0

Given the data frame below containing three variables, each repeated three times with exactly the same name, I want a function that renames each element of each set of variables with the same name according to both the name and the position, by for example adding .m the first time each variable from each set of variables with the same name appears, .l the second time, and .u the third time.

I am aware that I could do what I want manually using this, this, this, and other solutions. But for my case, some of my variables have the same name, so the only option that seems obvious to me is using column position to identify and rename the variables, which is not feasible for large dataset.

#data

dt<-structure(list(general = c(0.348886829202466, 
0.203589313542743, 0.90655704224777, 0.344599044114144, 0.301264059075478
), vocation = c(0.90007128724776, 0.25093350439507, 
0.840003175556854, 0.0763147760239838, 0.765717248505423), general = c(8.48536430252404, 
0.61215079555521, 0.33908999482637, 0.959941654100972, 0.577845916408486, 
0.551543184240344), vocation = c(208.71134987404, 1.68880630570487, 
0.428696219910234, 0.890082828242642, 0.16628759312575, 1.49119733964464
), general = c(239.145164960882, 1.07406919703872, 0.564774361632725, 
1.01646993662232, 0.968969324823085, 1.00974502240828), vocation = c(5980.31502662087, 
3.16871205491912, 0.732387049741986, 0.943148150133152, 0.362335645443876, 
2.90403475970219)), class = "data.frame", row.names = c( 
"sesmiddle", "seshigh", "write", "schtypprivate", "honorsenrolled"
))

#expected output

        general.m  general.l   general.u   vocation.m  vocation.l  vocation.u    
sesmiddle 0.3488868 0.6121508   1.0740692  0.90007129  1.6888063   3.1687121   
seshigh   0.2035893 0.3390900   0.5647744  0.25093350  0.4286962   0.7323870
write     0.9065570 0.9599417   1.0164699  0.84000318  0.8900828   0.9431482
schtypprivate  0.3445990 0.5778459   0.9689693 0.07631478   0.1662876    0.3623356
honorsenrolled 0.3012641 0.5515432   1.0097450 0.76571725   1.4911973    2.9040348

Thanks in advance for any help. Please kindly let me know in the comments if anything is not clear.

Krantz
  • 1,424
  • 1
  • 12
  • 31

1 Answers1

1

make.unique is probably the way to go generally but it will always append numbers. Here is a solution that works for your case:

f <- function(x){

  nms <- names(x)

  num <- sapply(1:length(nms), function(i) sum(nms[i] == nms[1:i]))

  suffix <- ifelse(num == 1, ".m", ifelse(num == 2, ".l", ".u"))

  names(x) <- paste0(nms, suffix)

  x

}

f(dt)
#               general.m vocation.m general.l  vocation.l   general.u   vocation.u
#sesmiddle      0.3488868 0.90007129 8.4853643 208.7113499 239.1451650 5980.3150266
#seshigh        0.2035893 0.25093350 0.6121508   1.6888063   1.0740692    3.1687121
#write          0.9065570 0.84000318 0.3390900   0.4286962   0.5647744    0.7323870
#schtypprivate  0.3445990 0.07631478 0.9599417   0.8900828   1.0164699    0.9431482
#honorsenrolled 0.3012641 0.76571725 0.5778459   0.1662876   0.9689693    0.3623356
dave-edison
  • 3,666
  • 7
  • 19