在列中转换具有冗余信息的行

时间:2016-06-22 21:34:34

标签: r

请将一些数据按行排列,我希望使用" R"如下:

这个想法是为了获得“等位基因,效果和障碍”。线条,排列成3行,转向列。 tag,Trait,Marker Locus每三行都是一样的,Allele,Effect和Obs会有什么变化。

例: 初始数据

data1 <-"tag Trait Marker Locus Site Allele Effect Obs
ca-S10_17086845 ca S10_17086845 10 17086845 R 0.000001  54
ca-S10_17086845 ca S10_17086845 10 17086845 A 3.489820   1
ca-S10_17086845 ca S10_17086845 10 17086845 G -0.017141 389
cf-S10_9890328  cf S10_9890328 10 9890328 R 0.000001 146
cf-S10_9890328  cf S10_9890328 10 9890328 G 4.367540   1
cf-S10_9890328  cf S10_9890328 10 9890328 A -0.010635 297"
data1 <-read.table(text=data1,header=T)

预期结果

data2 <- "Trait Marker Allele Ef1 Ef2 Ef3 Obs1 Obs2 Obs3
ca S10_17086845 R/A/G 0.000001 3.489820 -0.017141 54 1 389
cf S10_9890328 R/G/A 0.000001 4.367540 -0.010635 146 1 297"
data2 <-read.table(text=data2,header=T)

谢谢

4 个答案:

答案 0 :(得分:1)

您可以使用dplyr粘贴等位基因,也可以获得第一,第二和第三效果或者Obs。

library(dplyr)
data1 %>% group_by(Trait, Marker) %>% summarize( allele = paste(Allele, collapse="/"), ef1=first(Effect), ef2=nth(Effect,2) , ef3=nth(Effect,3) )

  Trait       Marker allele      ef1     ef2       ef3
1    ca S10_17086845  R/A/G 0.000001 3.48982 -0.017141
2    cf  S10_9890328  R/G/A 0.000001 4.36754 -0.010635

答案 1 :(得分:1)

可能有一种更简单的方法,但dplyr和tidyr的这个组合有效:

library(dplyr)
library(tidyr)
data3 <- data1 %>% 
          group_by(tag) %>% 
          mutate(obstag = paste0("Obs", seq_along(Obs)),  # Add markers
                 eftag = paste0("Ef", seq_along(Effect)),
                 altag = paste0("A", seq_along(Allele))) %>%
          spread(altag, Allele) %>%  # Switch from rows to columns 
          spread(obstag, Obs) %>% 
          spread(eftag, Effect) %>% 
          summarise_each(funs(unique(na.omit(.))), 1:Ef3) %>%  # Collapse into one row per tag 
          mutate(Allele = paste(A1, A2, A3, sep = "/")) %>% # paste alleles together
          select(-A1, -A2, -A3, -tag) # drop unwanted columns

答案 2 :(得分:1)

您可以使用dplyrtidyr尝试这样的操作,首先我们会删除两个不相关的列tagSite,我认为您应该在发布之前完成使想法更清晰;然后按TraitMarkerLocus组进行汇总,将AlleleEffect以及Obs粘贴在一起。最后,列EffectObs的分隔到达结果数据框:

library(dplyr); library(tidyr);
data1 %>% select(-tag, -Site) %>% group_by(Trait, Marker, Locus) %>% 
          summarise_each(funs(paste(., collapse = "/"))) %>% 
          separate(Effect, into = paste("Eff", 1:3, sep = ""), sep = "/") %>% 
          separate(Obs, into = paste("Obs", 1:3, sep = ""), sep = "/")

# Source: local data frame [2 x 10]
# Groups: Trait, Marker [2]
# 
#    Trait       Marker Locus Allele     Eff1    Eff2      Eff3  Obs1  Obs2  Obs3
#   (fctr)       (fctr) (int)  (chr)    (chr)   (chr)     (chr) (chr) (chr) (chr)
# 1     ca S10_17086845    10  R/A/G 0.000001 3.48982 -0.017141    54     1   389
# 2     cf  S10_9890328    10  R/G/A 0.000001 4.36754 -0.010635   146     1   297

答案 3 :(得分:1)

我们可以使用data.table轻松完成此操作。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(data1)),创建&#39; Allele1&#39;专栏paste&#39; Allele&#39;经过“特质”分组后,他们在一起和&#39; Marker&#39;。然后,使用dcast将其重新整形为“广泛”。格式。 data.table::dcastreshape2:dcast不同,因为它也可能需要多个value.var列。

library(data.table)#v1.9.7+
setDT(data1)[,  Allele1 := paste(Allele, collapse="/") , .(Trait, Marker)]
dcast(data1, Trait + Marker + Allele1 ~ rowid(Trait), 
                              value.var = c("Effect", "Obs"))
#   Trait       Marker Allele1 Effect_1 Effect_2  Effect_3 Obs_1 Obs_2 Obs_3
#1:    ca S10_17086845   R/A/G 0.000001  3.48982 -0.017141    54     1   389
#2:    cf  S10_9890328   R/G/A 0.000001  4.36754 -0.010635   146     1   297