Immaginate Ho un dataframe come questo (o i nomi di tutti i mesi)sottraendo ogni due colonne
set.seed(1)
mydata <- data.frame()
mydata <- rbind(mydata,c(1,round(runif(20),3)))
mydata <- rbind(mydata,c(2,round(runif(20),3)))
mydata <- rbind(mydata,c(3,round(runif(20),3)))
colnames(mydata) <- c("id", paste0(rep(c('Mary', 'Bob', 'Dylan', 'Tom', 'Jane', 'Sam', 'Tony', 'Luke', 'John', "Pam"), each=2), 1:2))
.
id Mary1 Mary2 Bob1 Bob2 Dylan1 Dylan2 Tom1 Tom2 Jane1 Jane2 Sam1 Sam2 Tony1 Tony2 Luke1 Luke2 John1 John2 Pam1 Pam2
1 0.266 0.372 0.573 0.908 0.202 0.898 0.945 0.661 0.629 0.062 0.206 0.177 0.687 0.384 0.770 0.498 0.718 0.992 0.380 0.777
2 0.935 0.212 0.652 0.126 0.267 0.386 0.013 0.382 0.870 0.340 0.482 0.600 0.494 0.186 0.827 0.668 0.794 0.108 0.724 0.411
3 0.821 0.647 0.783 0.553 0.530 0.789 0.023 0.477 0.732 0.693 0.478 0.861 0.438 0.245 0.071 0.099 0.316 0.519 0.662 0.407
Di solito con molte più colonne.
E voglio aggiungere colonne (sta a voi decidere di aggiungerli a destra, oppure creare una nuova dataframe con queste nuove colonne) sottraendo ogni due .. (*)
id, Mary1-Mary2, Bob1-Bob2, Dylan1-Dylan2, Tom1-Tom2, Jane1-Jane2,...
Questo l'operazione è abbastanza comune
Mi piacerebbe farlo per nome, non per posizione, per evitare problemi se non sono consecutivi. Potrebbe anche succedere che alcune colonne non abbiano la colonna "doppia", basta andarsene così com'è o ignorare questa complicazione ora.
(*) I nomi delle colonne hanno un prefisso e un numero. Invece di solo sottrarre due colonne, potrei avere gruppi di 5 e potrei voler fare qualcosa come aggiungere tutti i numeri. Una soluzione generica sarebbe grandiosa.
Prima ho provato a farlo convertendolo in formato lungo, in seguito operato con aggregato e convertendolo di nuovo in formato grande, ma forse è molto più facile farlo direttamente in formato grande. So che il problema riguarda principalmente l'uso di espressioni regolari in modo efficiente.
R, data.table or dplyr, long format splitting colnames
non mi dispiace la velocità, ma la soluzione più semplice. Qualsiasi pacchetto è benvenuto.
PD: tutti i codici falliscono se aggiungo una colonna solitaria. set.seed (1)
mydata <- data.frame()
mydata <- rbind(mydata,c(1,round(runif(21),3)))
mydata <- rbind(mydata,c(2,round(runif(21),3)))
mydata <- rbind(mydata,c(3,round(runif(21),3)))
colnames(mydata) <- c(c("id", paste0(rep(c('Mary', 'Bob', 'Dylan', 'Tom', 'Jane', 'Sam', 'Tony', 'Luke', 'John', "Pam"), each=2), 1:2)),"Lola")
so che potrei filtrare manualmente, ma sarebbe meglio se il risultato è la differenza (*) di ogni coppia e lasciare solo la colonna solitaria. (In caso di differenze di gruppi di due dimensioni)
L'opzione migliore non sarebbe rimuovere manualmente la prima colonna ma dividere tutte le colonne in colonne singole e multiple.
'potrebbe avere gruppi di 5' - in modo che quando i nomi hanno gruppi di X, saranno tutti i nomi hanno una quantità X di colonne? o avresti dei casi in cui solo Bob ha 5 colonne e Mary ha solo 2 colonne? – zx8754
Ma a seconda dell'operazione potrebbe essere possibile o meno. Ad esempio, è possibile calcolare la media di gruppi di dimensioni diverse, ma alcune altre operazioni non possono essere definite. – skan
Puoi mantenerlo semplice se vuoi. Tranne ciò che ho detto: "Potrebbe anche accadere che alcune colonne non abbiano la doppia colonna". Se una colonna è sola (dimensione del gruppo = 1) lasciala così com'è. Diciamo che tutti gli altri hanno le stesse dimensioni. Quindi, abbiamo size = 1 o size = N, con N fisso. – skan