更改数据框中的交错行

时间:2015-12-08 23:00:01

标签: r

我有一个12700 x 307数据框,其中包含以下基因数据:列中的个别ID编号,行中的基因座标识(每个基因座注意两行)

alist<-c("loci",185,186,187,188,189,190,191,"A549",1,1,1,1,1,1,1,"A549",0,0,1,1,1,0,1,"A588",1,1,1,1,1,1,1,"A588",0,0,0,0,0,0,1,"A794",1,1,1,1,1,1,1,"A794",1,0,1,0,1,1,0,"A081",1,1,1,1,1,1,0,"A081",1,1,1,1,1,1,1)
df <- data.frame(matrix(unlist(alist), nrow=9, byrow=T),stringsAsFactors=FALSE)
colnames(df) = df[1, ]
df<-df[-1, ]  

我需要将其更改为每个个体有两行的数据框,每个基因座一列。第一行个体应该具有第一等位基因的存在/缺失条目,第二行应该具有该基因座的第二等位基因。

所以看起来应该是这样的:

blist<-c("individual","A549","A588","A794","A081","185",1,1,1,1,"185",0,0,1,1,"186",1,1,1,1,"186",0,0,0,1,"187",1,1,1,1,"187",1,0,1,1,"188",1,1,1,1,"188",1,0,0,1,"189",1,1,1,1,"189",1,0,1,1,"190",1,1,1,1,"190",0,0,1,1,"191",1,1,1,0,"191",1,1,0,1)
dfb <- data.frame(matrix(unlist(blist), nrow=15, byrow=T),stringsAsFactors=FALSE)
colnames(dfb) = dfb[1, ]
dfb<-dfb[-1, ]

它一定是可以做到但我没有看到它。我很感激任何想法。

2 个答案:

答案 0 :(得分:1)

以下是使用dplyrtidyr的方法。

它的工作原理是gather您的数据。

然后是group_by个位置和个人,mutates位于row_number,因为您有重复的ID。

然后spread按指定的方向返回长,select出行列:

library(dplyr)
library(tidyr)
df %>% gather(individual, val, -loci) %>%
       group_by(loci, individual) %>%
       mutate(row = row_number()) %>%
       spread(loci, val) %>%
       select(-row)

   individual  A081  A549  A588  A794
       (fctr) (chr) (chr) (chr) (chr)
1         185     1     1     1     1
2         185     1     0     0     1
3         186     1     1     1     1
4         186     1     0     0     0
5         187     1     1     1     1
6         187     1     1     0     1
7         188     1     1     1     1
8         188     1     1     0     0
9         189     1     1     1     1
10        189     1     1     0     1
11        190     1     1     1     1
12        190     1     0     0     1
13        191     0     1     1     1
14        191     1     1     1     0

答案 1 :(得分:1)

使用各种数据管理程序考虑这个基本R解决方案。如果只是将列号中的8引用更改为全长列,则将其设置为按比例缩放到实际生产数据:

# TRANSPOSING DATA FRAME
tdf <- as.data.frame(t(df[,-1]))

# SETTING COLUMN NAMES
names(tdf) <- as.list(df$loci)    
# SETTING INDIVIDUAL COLUMN
tdf$individual <- rownames(tdf)

# STACK SAME COLUMNS (CHANGE 8 TO NUMBER OF COLS(307))
finaldf <- rbind(tdf[, c(ncol(tdf), seq(1, 8, 2))],   # EVEN COLS
                 tdf[, c(ncol(tdf), seq(2, 8, 2))])   # ODD COLS

# ORDER BY INDIVIDUAL COLUMN
finaldf <- finaldf[with(finaldf, order(individual)), ]
rownames(finaldf) <- 1:nrow(finaldf)

# CONVERT LOCI COLUMNS TO NUMERIC
finaldf[,-1] <- sapply(sapply(finaldf[,-1], as.character), as.numeric)

<强>输出

    individual  A549    A588    A794    A081
1         185      1       1       1       1
2         185      0       0       1       1
3         186      1       1       1       1
4         186      0       0       0       1
5         187      1       1       1       1
6         187      1       0       1       1
7         188      1       1       1       1
8         188      1       0       0       1
9         189      1       1       1       1
10        189      1       0       1       1
11        190      1       1       1       1
12        190      0       0       1       1
13        191      1       1       1       0
14        191      1       1       0       1