R 选择数据帧列表的最后一个非NA列

R 选择数据帧列表的最后一个非NA列,r,list,dataframe,lapply,R,List,Dataframe,Lapply,我目前正在尝试解析R中的RDP多分类层次结构文件,但是这个问题更普遍。基本上,我创建了一个列表,其中包含多个文件的数据帧,这些文件包含“分层”行: 这基本上意味着我有渐进的行,在渐进的列中用NA填充。但是,无法确定第一个NA将在哪一行。在第一列NA之前,我有两列真正让我感兴趣的内容:指定分类级别的重叠群数量计数,以及分类级别名称前的两列 我已经创建了一个列表,其中包含每个数据帧的索引,这些索引将通过以下方式选择最后一行: library(plyr) lastcollist<-lapply(

我目前正在尝试解析R中的RDP多分类层次结构文件,但是这个问题更普遍。基本上,我创建了一个列表,其中包含多个文件的数据帧,这些文件包含“分层”行:

这基本上意味着我有渐进的行,在渐进的列中用NA填充。但是,无法确定第一个
NA
将在哪一行。在第一列NA之前,我有两列真正让我感兴趣的内容:指定分类级别的重叠群数量计数,以及分类级别名称前的两列

我已经创建了一个列表,其中包含每个数据帧的索引,这些索引将通过以下方式选择最后一行:

library(plyr)
lastcollist<-lapply(hierlist,function(p)lapply(apply(p, 1, function(x) which(!is.na(x)) ),function(x)if(length(x)>0){max(x)}else{0}))
lastcollist<-lapply(lastcollist,unlist)
lastcollist.idx<-llply(lastcollist,function(x)cbind(seq(1,length(x)),x))
所以我现在基本上想做的是创建一个新的列表,其中包含数据帧(或者在只有最后一列的情况下,变量
x
in
lastclist.idx
),每个给定行都有最后选择的列

这将是给定示例的期望输出:

 dput(rbind(c('domain','194'),c('Proteobacteria','Phylum'),c('Betaproteobacteria','class'),c ('class','Rhodocyclales'),c('class','Rhodocyclales'),c('class','Rhodocyclales')))
structure(c("domain", "Proteobacteria", "Betaproteobacteria", 
"class", "class", "class", "194", "Phylum", "class", "Rhodocyclales", 
"Rhodocyclales", "Rhodocyclales"), .Dim = c(6L, 2L))
我必须承认,我不会马上知道怎么做。欢迎任何指点。我不是R的新手,所以你不必花太多时间来解释

对于一个更大的可重复的例子,考虑来自生物导体库IMPUT()的数据集“Khan思念”。p> 它基本上是一个数据帧,在几个地方引入了NAs。它与我的文件的层次结构并不完全相同,但它将符合目的。由于这是一个非常不方便的数据帧,有2309个观察值,并且其中只有222行包含缺失值,因此我选择了缺失值的行,并在新的data.frame中随机添加了78行没有缺失值的行。然后将此data.frame拆分为4个任意大小的数据帧列表(总计300个)


isnadf一些未经测试的东西可能会起作用:

apply(dfrm, 1, function(r) { r[ (which(is.na(r))[1]-1):(which(is.na(r))[1]-2)) ] } )
在这个例子中,我加载文本输出作为数据帧的常用方法失败了,因此我的建议是发布
dput
输出,而不是屏幕抓取。(在我看来,您应该使用header=TRUE进行数据输入,因为您的第一行数据看起来不像数据。)

有了新数据(并认识到无NA测试的必要性:

 apply(hierlist, 1, function(r) { r[ 
                      if( any(is.na(r))){ 
                          (which(is.na(r))[1]-1):( which(is.na(r))[1]-2) 
                       }else{
                          (length(r)-2): (length(r)-1)}
                                      ] }
       )
#--------------------------------------
     2         3          4                5                   
[1,] "194"     "domain"   "phylum"         "class"             
[2,] "no rank" "Bacteria" "Proteobacteria" "Betaproteobacteria"
     6                    7                    8                   
[1,] "Betaproteobacteria" "Betaproteobacteria" "Betaproteobacteria"
[2,] "class"              "class"              "class" 


我们是否应该了解RDP多分类层次结构文件以提供帮助?如果不知道,我必须承认这很难理解。您能否将其简化为一些小的内容(例如,为什么告诉我们您有一个data.frames列表,而不仅仅是一个data.frames?)而且很容易理解,有一个输入和预期输出的示例。不过,我将向您指出矩阵索引是一个可能的解决方案。例如,请参见它的作用:
m Hi@flodel,这是一个更一般的问题,但输入列表很难一般生成。dput结构将是巨大的(它是一个2 Mb的列表)。我将尝试重新表述我的问题:我有一个数据帧列表,因为我使用read.table读取了多个(30多个)文件。每个文件在列表中形成一个新的data.frame。手动创建每个数据帧相当费劲,而且这些文件是通过从目录中对某些文件进行灰色化来读取的,因此文件量可以更改。(……)ctd问题是,对于每一个数据帧,我需要不包含“NA”的每一行最后一列的值,以及在此之前两列的同一行上的值。最后一列的索引可以更改每一行。最后,我的输出应该是一个包含两列的data.frames的列表。感谢有关矩阵索引的提示,但是我宁愿不必为了操作而来回地从df转换到矩阵。好吧,理想的情况是你手动创建一个data.frame,比如说,六列五行,在适当的位置使用NA来处理所有情况。以及预期的输出。你的
角(hierlist$hier_M2MID06_Trimmed_noGaps.fas_fixrank.txt,n=c(7,10))
算是一个不错的例子,你可以只给出所有称之为数据的
dput
。另外,当我说预期输出时,我指的是确切的数据结构以及解释。Hi@IShouldBuyABoat,我没有加载header=t的原因是源文件中的列数可变。我是awar第一行是“header-like”,但实际上我对这一行不感兴趣。我只是用一些模式将我的文件列表灰显:
filei我试图对列表进行dput,但它太大了(2Mb)。即使尝试只输出列表中的两个元素也是不可能的,因为R控制台没有提供足够长的输出,我也无法以任何方式发布。在上,您将找到指向列表第一个数据帧的dput的链接。其他数据帧具有类似的结构。
dput(head(dfrm,30))
正如您在我对问题所做的编辑和与flodel的讨论中所看到的,我现在提供了数据帧角的dput(角是来自包BurstDisc的函数,基本上是一个二维头函数)。
 source("http://bioconductor.org/biocLite.R")
 biocLite("impute")
 require(impute)
 data(khanmiss)
isnadf<-as.data.frame(which(is.na(khanmiss),arr.ind=T))
na.rows<-sort(unique(isnadf$row))
length(na.rows) #the dataset has 222 rows which contain NA
na.khanmiss<-khanmiss[na.rows,]
notna.rows<-setdiff(rownames(khanmiss),na.rows)
notna.rows.selected<-sort(as.numeric(sample(notna.rows,78)))
notna.selected.khanmiss<-khanmiss[notna.rows.selected,]
khanmiss.selected<-rbind(na.khanmiss,notna.selected.khanmiss)
dfsizes<-c(82,74,79,65) #arbitrarily selected, adds up to 300
khanmiss.list<-split(khanmiss.selected,rep(letters[1:4],dfsizes))
apply(dfrm, 1, function(r) { r[ (which(is.na(r))[1]-1):(which(is.na(r))[1]-2)) ] } )
 apply(hierlist, 1, function(r) { r[ 
                      if( any(is.na(r))){ 
                          (which(is.na(r))[1]-1):( which(is.na(r))[1]-2) 
                       }else{
                          (length(r)-2): (length(r)-1)}
                                      ] }
       )
#--------------------------------------
     2         3          4                5                   
[1,] "194"     "domain"   "phylum"         "class"             
[2,] "no rank" "Bacteria" "Proteobacteria" "Betaproteobacteria"
     6                    7                    8                   
[1,] "Betaproteobacteria" "Betaproteobacteria" "Betaproteobacteria"
[2,] "class"              "class"              "class"