1
votes

Addition d'une colonne particulière à n nombre de colonnes dans toutes les 2 et 3 combinaisons possibles

J'ai un ensemble de données de 240 colonnes et 146 lignes. Je ne fournis que les premiers morceaux de l'ensemble de données avec 5 lignes

D1+S3
D2+S3
D3+S3
D1+D2+S3
D1+D3+S3

Je veux ajouter chaque 4ème colonne (c'est-à-dire S3) avec les 3 colonnes précédentes comme combinaisons suivantes

DF <- data.frame(
          D1 = c(-0.253, 0.253, -0.951, 0.951, 0.501, -0.501),
          D2 = c(-0.52, -0.52, 0.52, 0.52, -0.172, -0.172),
          D3 = c(0.014, 0.014, 0.014, 0.014, -0.014, -0.014),
          S3 = c(0.095, 0.095, 0.095, 0.095, 0.095, 0.095),
          D1 = c(-0.966, 0.966, -0.647, 0.647, 0.905, -0.905),
          D2 = c(-0.078, -0.078, 0.078, 0.078, -0.943, -0.943),
          D3 = c(-0.046, -0.046, -0.046, -0.046, 0.046, 0.046),
          S3 = c(0.07, 0.07, 0.07, 0.07, 0.07, 0.07)
)

Dans le nouveau dataframe, les colonnes devraient être
D1 D2 D3 S3 D1 + S3 D2 + S3 D3 + S3 D1 + D2 + S3 D1 + D3 + S3 D1 D2 D3 S3 D1 + S3 D2 + S3 D3 + S3 D1 + D2 + S3 D1 + D3 + S3

Comment le faire en R? Toute aide à cet égard est très appréciée.


2 commentaires

Pouvez-vous publier des exemples de données au format dput ? Veuillez modifier la question avec la sortie de dput (df) . Ou, s'il est trop gros avec la sortie de dput (head (df, 20)) . ( df est le nom de votre ensemble de données.)


Y a-t-il une logique dans ces combinaisons?


3 Réponses :


3
votes

Dans le code suivant, je remodèle votre bloc de données pour qu'il rassemble toutes les valeurs dans 4 colonnes. Pour distinguer les colonnes d'origine, j'ai ajouté une colonne ID. Après cela, l'opération que vous souhaitez effectuer devient facile.

n_decomp <- 3
n_var <- n_decomp + 1
i <- seq(1, ncol(df), n_var)
df_names <- names(df[1:n_var])

df_out <- 
  map_dfr(i,
          ~select(df, seq(., .+n_decomp)) %>%
            set_names(df_names)) %>% 
  mutate(id = rep(1:length(i), each = nrow(df)))


decomp_combn <- map(1:n_decomp, 
    ~combn(df_names[1:n_decomp], .) %>% 
      as_tibble %>% 
      as.list) %>% 
  flatten() %>% 
  map(c, "S3")

decomp_combn %>% 
  map(~select(df_out, .)) %>%
  set_names(map(., ~str_c(names(.), collapse = "_"))) %>% 
  map(~apply(., 1, sum)) %>% 
  as_tibble %>% 
  bind_cols(df_out, .)

Si vous souhaitez le remettre à sa forme d'origine après cela, vous pouvez faire ce qui suit.

df_out %>% 
  group_split(id) %>% 
  bind_cols()

Modifier: J'ai réécrit le code pour travailler pour un nombre variable de décompositions. Vous devriez juste avoir à changer n_decomp par le nombre approprié. Il crée des variables pour toutes les combinaisons possibles des variables de décomposition avec S3. Donc, il s'aggravera rapidement avec un nombre croissant de décompositions.

library(tidyverse)

df <- read_table(
"D1         D2     D3      S3      D1       D2      D3    S3
-0.253  -0.520  0.014   0.095   -0.966  -0.078  -0.046  0.070
0.253   -0.520  0.014   0.095   0.966   -0.078  -0.046  0.070
-0.951  0.520   0.014   0.095   -0.647  0.078   -0.046  0.070
0.951   0.520   0.014   0.095   0.647   0.078   -0.046  0.070
0.501   -0.172  -0.014  0.095   0.905   -0.943  0.046   0.070
-0.501  -0.172  -0.014  0.095   -0.905  -0.943  0.046   0.070
")

i <- seq(1, ncol(df)-3, 4)

df_out <- map_dfr(i, ~select(df, seq(., .+3)) %>% set_names(c("D1", "D2", "D3", "S3"))) 

df_out %>% 
  mutate(d1d2s3 = D1 + D2 + D3,
         d1d3s3 = D1 + D3 + D3,
         id = rep(1:length(i), each = nrow(df))) %>% 
  mutate_at(1:3, ~.+S3) %>% 
  bind_cols(df_out, .)


8 commentaires

Pouvez-vous rendre les nombres plus intuitifs afin que lorsque le nombre de décompositions (Ds) augmente, le code fonctionne correctement?


Merci pour votre code. Cela fonctionne bien mais ne donne que D1 + S3 D2 + S3 D3 + S3 . Les combinaisons D1 + D2 + S3 D1 + D3 + S3 ne sont pas disponibles.


J'ai oublié d'inclure D1 + D2 + S3 et D1 + D3 + S3 , mais j'ai édité l'article pour les inclure, mais en l'adaptant à un nombre variable de décompositions ça va être un peu plus compliqué


Maintenant c'est parfaitement bien. Pouvons-nous ajouter / conserver toutes les séries originales également dans la trame de données?


J'ai changé le code d'origine pour conserver les variables d'origine. De plus, j'ai ajouté du code pour un nombre variable de décompositions.


Maintenant, il ne donne toutes les combinaisons possibles que pour la première décomposition. D'autres décompositions sont manquantes.


Le code en bas ne produit pas une trame de données avec 12 colonnes pour vous?


Merci beaucoup. Le deuxième morceau vient en dessous du premier. J'ai résolu mon problème. Merci beaucoup.



0
votes

Assez long mais devrait fonctionner:

data<-read.csv("Decompositions_1.csv")
nc_input=ncol(data)
nc_output = (ncol(data)/4)*5
output <- data.frame(as.data.frame(matrix(0,ncol=nc_output,nrow=nrow(data))))
firsts=data[,seq(1,nc_input,4)]
seconds=data[,seq(2,nc_input,4)]
thirds=data[,seq(3,nc_input,4)]
fourths=data[,seq(4,nc_input,4)]
starts_ou=seq(1,nc_output,5)
subsets=1:length(starts_ou)
for(i in subsets) {
ou_index=starts_ou[i]
output[,ou_index]=firsts[i]+fourths[i]
output[,ou_index+1]=seconds[i]+fourths[i]
output[,ou_index+2]=thirds[i]+fourths[i]
output[,ou_index+3]=firsts[i]+thirds[i]+fourths[i]
output[,ou_index+4]=seconds[i]+thirds[i]+fourths[i]
}


0 commentaires

0
votes

Un peu tard - mais voici une approche data.table :

       D1     D2     D3    S3     D1     D2     D3   S3  D1+S3  D2+S3 D3+S3 D1+D2+S3 D1+D3+S3
1: -0.253 -0.520  0.014 0.095 -0.966 -0.078 -0.046 0.07 -0.158 -0.425 0.109   -0.678   -0.144
2:  0.253 -0.520  0.014 0.095  0.966 -0.078 -0.046 0.07  0.348 -0.425 0.109   -0.172    0.362
3: -0.951  0.520  0.014 0.095 -0.647  0.078 -0.046 0.07 -0.856  0.615 0.109   -0.336   -0.842
4:  0.951  0.520  0.014 0.095  0.647  0.078 -0.046 0.07  1.046  0.615 0.109    1.566    1.060
5:  0.501 -0.172 -0.014 0.095  0.905 -0.943  0.046 0.07  0.596 -0.077 0.081    0.424    0.582
6: -0.501 -0.172 -0.014 0.095 -0.905 -0.943  0.046 0.07 -0.406 -0.077 0.081   -0.578   -0.420

library(data.table)

DT <- data.table(
          D1 = c(-0.253, 0.253, -0.951, 0.951, 0.501, -0.501),
          D2 = c(-0.52, -0.52, 0.52, 0.52, -0.172, -0.172),
          D3 = c(0.014, 0.014, 0.014, 0.014, -0.014, -0.014),
          S3 = c(0.095, 0.095, 0.095, 0.095, 0.095, 0.095),
          D1 = c(-0.966, 0.966, -0.647, 0.647, 0.905, -0.905),
          D2 = c(-0.078, -0.078, 0.078, 0.078, -0.943, -0.943),
          D3 = c(-0.046, -0.046, -0.046, -0.046, 0.046, 0.046),
          S3 = c(0.07, 0.07, 0.07, 0.07, 0.07, 0.07)
)

DT[, c("D1+S3", "D2+S3", "D3+S3", "D1+D2+S3", "D1+D3+S3") := list(D1+S3, D2+S3, D3+S3, D1+D2+S3, D1+D3+S3)]

DT


5 commentaires

Merci pour votre réponse. Dans le code actuel, vous fournissez les combinaisons manuellement. Mais dans l'ensemble de données d'origine, de nombreuses colonnes sont présentes et, à des fins de représentation, j'ai fourni une petite partie des données. Donc, ce serait mieux si cela peut être fait de manière dynamique. Vous pouvez voir les commentaires de la réponse acceptée.


Ok, juste une question secondaire: D1, D2, D3, S3 sont deux fois dans votre ensemble de données. S'agit-il de deux tableaux distincts?


J'ai de nombreuses colonnes et j'ai décomposé chaque colonne en Ds et Ss.


Il est donc intentionnel que vous ayez des noms de colonnes en double?


Oui, c'est comme ça seulement, même si ce n'est pas obligatoire.