1

我有一个制表符分隔的文件abc.txt

contig  score   guide
1:100-101   7   AAA
1:100-101   6   BBB
1:100-101   5   CCC
1:100-101   4   DDD
1:100-101   3   EEE
1:100-101   2   FFF
1:100-101   1   GGG
1:100-101   90  HHH
1:100-101   111 III
1:100-101   1111    JJJ
1:200-203   503.5333333 KKK
1:200-203   570.7212121 LLL
1:200-203   637.9090909 MMM
1:200-203   705.0969697 NNN
1:200-203   772.2848485 OOO
1:200-203   839.4727273 PPP
1:200-203   906.6606061 QQQ
1:200-203   973.8484848 RRR
2:300-301   1041.036364 SSS
2:300-301   1108.224242 TTT
2:300-301   1175.412121 UUU
2:300-301   1242.6  VVV
2:300-301   1309.787879 ABC
2:300-301   1376.975758 CGA
2:300-301   1444.163636 ACD

第 1 列-Contig 有多个重复值,第 2 列有分数,第 3 列有与第 2 列分数对应的引导字母。我需要为第一列(contig)中的相似值选择前 5 个分数,并在那里打印对应的第 3 列值。

输出应如下所示,第一列具有唯一的列 1-Contig 条目,接下来的 10 行用于前 5 个分数和相应的列 3 引导字母

    Score-1 Guide-1 Score-2 Guide-2 Score-3 Guide-3 Score-4 Guide-4 Score-5 Guide-5
1:100-101   1111    JJJ 111 III 90  HHH 7   AAA 6   BBB
1:200-203   973.8484848 RRR 906.6606061 QQQ 839.4727273 PPP 772.2848485 OOO 705.0969697 NNN
2:300-301   1444.163636 ACD 1376.975758 CGA 1309.787879 ABC 1242.6  VVV 1175.412121 UUU

我使用了“dplyr”和“desctools”包,但是运行时出现了一些错误。

library(dplyr)
library(DescTools)
file <- "abc.txt"
x=read.table(file)
b <- Large(x, k=5, unique = FALSE, na.last=NA)

并得到这个错误

Error in Large(x, k = 5, unique = FALSE, na.last = NA) : 
  Not compatible with requested type: [type=character; target=double].

我被要求在 excel 中使用“sumproduct、large、iferror 和 vllokup”公式执行此操作,但是对于大型数据集,我想使用 R 提取文件。

任何帮助都感激不尽

4

2 回答 2

1

无需搜索解决此问题的软件包 - base R 拥有您需要的一切。

首先我们要处理groupwise操作,所以我们contig通过函数根据groupvariable拆分数据帧split()。我们得到一个数据框列表。为了将我们的操作应用于其中的每一个,我们可以使用lapply(),它将给定的函数应用于所有列表元素。我们构建了一个函数,它选择提供的数据框的前 5 行x,按score(降序-x$score)排序。我们将结果分配给z。以下do.call(data.frame, split…)结构仅将结果重塑为预期形式。

剩下的唯一事情是将列表打包到数据框并设置列名。

ll <- lapply(split(abc, abc$contig), function(x) {
      z <- x[order(-x$score)[1:5], 2:3]
      do.call(data.frame, split(z, 1:5))
    })

ll         # we're almost there …

$`1:100-101`
  X1.score X1.guide X2.score X2.guide X3.score X3.guide X4.score X4.guide X5.score X5.guide
10     1111      JJJ      111      III       90      HHH        7      AAA        6      BBB

$`1:200-203`
   X1.score X1.guide X2.score X2.guide X3.score X3.guide X4.score X4.guide X5.score X5.guide
    18 973.8485      RRR 906.6606      QQQ 839.4727      PPP 772.2848      OOO  705.097      NNN

$`2:300-301`
   X1.score X1.guide X2.score X2.guide X3.score X3.guide X4.score X4.guide X5.score X5.guide
25 1444.164      ACD 1376.976      CGA 1309.788      ABC   1242.6      VVV 1175.412      UUU

# … only pack the list to a data frame and set the columnnames
d.frm <- (do.call(rbind, ll))
colnames(d.frm) <- c(paste("Guide", 1:5), paste("Score", 1:5))[as.vector(t(matrix(1:10, nrow=5)))]

d.frm

            Guide 1 Score 1   Guide 2 Score 2   Guide 3 Score 3   Guide 4 Score 4  Guide 5 Score 5
1:100-101 1111.0000     JJJ  111.0000     III   90.0000     HHH    7.0000     AAA    6.000     BBB
1:200-203  973.8485     RRR  906.6606     QQQ  839.4727     PPP  772.2848     OOO  705.097     NNN
2:300-301 1444.1636     ACD 1376.9758     CGA 1309.7879     ABC 1242.6000     VVV 1175.412     UUU
于 2019-06-23T12:18:19.870 回答
1

问题很大,需要一个数字向量,而不是整个数据帧。这只是一个猜测,因为我没有可重现的示例,但您可能希望按照以下方式做一些事情:

library(dplyr)
library(DescTools)
file <- "./abc.txt"
x=read.table(file)
colnames(x)<-c("contig","score","guide")
x<-x[-1,]

list <- split(x , f = x$contig )
columntitles<-c()
for (i in 1:5)
  columntitles<-c(columntitles,paste0("guide-",i),paste0("score-",i))
x = data.frame(matrix(NA, nrow = 1, ncol = 10)) 
colnames(x)<-columntitles

for (i in 1:3){
  singlerow<-c()
  partialdata<-list[[i]]
  partialdata<-partialdata%>% top_n(5, score)
  partialdata<-partialdata[Rev(order(partialdata$score)),]
  for (j in 1:5){
    singlerow<-c(singlerow,toString(partialdata$guide[j]),toString(partialdata$score[j]))

  }
  x<-rbind(x,singlerow)
}
x<-x[-1,]
于 2019-06-21T17:07:14.700 回答