开发者

Modify the content of a dataframe in R

I would like to transform/modify the content of dataframe. Basically I have a dataframe like below:

        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

And I would like to transform/modify into another dataframe like this, where I split the content of my "bins" column (first row) into 150 rows containing the same values. And so on for the second row.

    chr开发者_Python百科  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...

Any help much appreciated,

Ben


The quick answer which may be, I fear, too specific and may need generalization. Assume the first dataframe is named "df1":

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

Argument recycling should make the "chr" long enough without a rep function.

Edit in reply to comment. If the repeat length is always 150 then the fix is easy:

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


Here's an attempt at a more generalized answer that could be made more efficient. I couldn't find an easy way to convert from a factor to numeric while retaining the levels in the new numeric column. Regardless, this should work and can support different values for the "chr" column and different numbers of rows:

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)]


Firs import with stringsAsFactors = FALSE in order not to get factors (or use Chase answer to convert to character):

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)

Now, the rest:

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
...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜