2010-11-30 8 views
4

Je voudrais transformer/modifier le contenu de la trame de données. Fondamentalement, j'ai un dataframe comme ci-dessous:Modifier le contenu d'une trame de données dans R

 bins  pval 
1 2L:1:150 0.9224217 
2 2L:151:300 0.9478824 
3 2L:301:450 0.9671139 
4 2L:451:600 0.9280847 
5 2L:601:750 0.9698584 
6 2L:751:900 0.9725379 

Et je voudrais transformer/modifier dans une autre dataframe comme celui-ci, où je partage le contenu de ma colonne « bacs » (première ligne) en 150 lignes contenant le même valeurs. Et ainsi de suite pour la deuxième rangée.

chr pos pval 
1 2L 1 0.9224217 
2 2L 2 0.9224217 
3 2L 3 0.9224217 
4 2L 4 0.9224217 
5 2L 5 0.9224217 
... 
150 2L 150 0.9224217 
151 2L 151 0.9478824 
152 2L 152 0.9478824 
153 2L 153 0.9478824 
etc... 

Toute aide très appréciée,

Ben

Répondre

2

La réponse rapide qui peut être, je le crains, trop spécifique et peut-être besoin de généralisation. Supposons que la première trame de données est nommée "df1":

data.frame (chr = "2L", pos = 1: (150 * NROW (df1)), pval = rep (df1 $ pval, chacun = 150))

Le recyclage d'arguments devrait rendre le "chr" assez long sans fonction rep.

Modifier en réponse à commenter. Si la longueur de répétition est toujours 150 alors la solution est facile:

data.frame(chr = rep(substr(df1$bins, 1,2), each=150), 
      pos = 1:(150*NROW(df1)), 
      pval = rep(df1$pval, each=150)) 
+0

Cela fonctionnerait si "chr" est toujours "2L", mais je n'ont des bacs tels que 3R: 1: 150, 4 l: 1: 150, etc .... Donc la colonne 'chr' n'est pas un const fourmi. –

+0

Cela fonctionne parfaitement en environ 2 ou 3 min avec un data.frame de 1 million de lignes. Merci. –

0

est ici une tentative de réponse plus générale qui pourrait être rendu plus efficace. Je ne pouvais pas trouver un moyen facile de convertir d'un factor à numeric tout en conservant les niveaux dans la nouvelle colonne numeric. Quoiqu'il en soit, cela devrait fonctionner et peut prendre en charge les différentes valeurs de la colonne et les différents « chr » nombre de lignes:

library(plyr) 

df <- read.table(textConnection("  bins  pval 
1 2L:1:150 0.9224217 
2 2L:151:300 0.9478824 
3 2L:301:450 0.9671139 
4 2L:451:600 0.9280847 
5 2L:601:750 0.9698584 
6 2L:751:900 0.9725379 
"), header = TRUE) 

#Split bins 
df.split <- data.frame(matrix(unlist(strsplit(as.character(df$bins), ":")), ncol = 3, byrow = TRUE)) 

colnames(df.split) <- c("chr", "low", "high") 

df.split$low <- as.numeric(as.character(df.split$low)) 
df.split$high <- as.numeric(as.character(df.split$high)) 

#Attach the pval from original df 
df.split$pval <- df[, 2] 

df.new <- adply(df.split, 1, summarise, pos = (low - 1) + seq(low:high)) 
df.new <- df.new[, c(1, 5, 4)] 
+0

Le facteur qui convient à la coercition numérique est un R-FAQ: num <- as.numeric (as.character (fac)) –

+0

@Dwin - c'est en effet beaucoup plus simple! – Chase

+0

J'ai testé ce code avec mon data.frame qui contient plus de 1 million de lignes, et il fonctionne toujours ... –

0

Firs importation avec stringsAsFactors = FALSE afin de ne pas obtenir des facteurs (ou utiliser Chase réponse à convertir au caractère):

df <- read.table(textConnection("  bins  pval 
1 2L:1:150 0.9224217 
2 2L:151:300 0.9478824 
3 2L:301:450 0.9671139 
4 2L:451:600 0.9280847 
5 2L:601:750 0.9698584 
6 2L:751:900 0.9725379 
"), header = TRUE, stringsAsFactors = FALSE) 

maintenant, le reste:

split <- strsplit(df$bins, ":") 
df$chr <- sapply(split, "[[", 1) 
reps <- sapply(split, function(el) diff(as.numeric(el[2:3]))+1) 
df[rep(1:nrow(df), reps), c("chr", "pval")] 

     chr  pval 
1  2L 0.9224217 
1.1 2L 0.9224217 
1.2 2L 0.9224217 
1.3 2L 0.9224217 
1.4 2L 0.9224217 
1.5 2L 0.9224217 
1.6 2L 0.9224217 
1.7 2L 0.9224217 
1.8 2L 0.9224217 
1.9 2L 0.9224217 
1.10 2L 0.9224217 
... 
Questions connexes