将矩阵列表转换为单个数据帧

时间:2017-06-23 19:29:33

标签: r

我有一个数据框:

 data=read.table(text="region     plot    species
 1          1A      A_B  
 1          1B      B_C
 1          1C      A_B
 1          1D      C_D
 2          2A      B_C
 2          2A      E_F
 2          2B      B_C
 2          2B      E_F     
 2          2C      E_F
 2          2D      B_C
 3          3A      A_B
 3          3B      A_B",stringsAsFactors=F,h=T) 

从该数据框中得到了一个矩阵列表:

sublist=NA
for (i in unique(data$region)){   
  sublist[i]<-list(subset(data, data[,1] == i))  
  print(i)
}

 results = list()
 for (r in unique(data$region)){
  myset<-split(sublist[[r]][[3]],sublist[[r]][[2]])
  output<- matrix(NA, nrow = length(myset), ncol = length(myset))
  rownames(output)<-colnames(output)<-unique(sublist[[r]][[2]])
  for (j in 1:(length(myset)-1)){
    for (i in (j+1):length(myset)){
    output[i,j]=sum(myset[[j]] %in% myset[[i]])
     }
   }
 results[[r]]=output
 }

以下是输出的显示方式(注意:它们的尺寸不同并包含NA):

 [[1]]
   1A 1B 1C 1D
1A NA NA NA NA
1B  0 NA NA NA
1C  1  0 NA NA
1D  0  0  0 NA

[[2]]
   2A 2B 2C 2D
2A NA NA NA NA
2B  2 NA NA NA
2C  1  1 NA NA
2D  1  1  0 NA

[[3]]
   3A 3B
3A NA NA
3B  1 NA 

我想将一个函数应用于这个矩阵列表,它将格式更改为一个数据帧。数据框的一列是矩阵元素,第二列是矩阵的行和列维度,第三列是包含矩阵填充值的freq列。对于此示例,输出将如下所示:(注意:不考虑NA。

output<-
      x     y       freq
      1     1A_1B     0     
      1     1A_1C     1
      1     1A_1D     0
      1     1B_1C     0    
      1     1B_1D     0 
      1     1C_1D     0
      2     2A_2B     2     
      2     2A_2C     1
      2     2A_2D     1
      2     2B_2C     1    
      2     2B_2D     1 
      2     2C_2D     0
      3     3A_3B     1  

我并不反对将第一个/原始数据帧转换为此输出数据帧以绕过循环和矩阵列表的更有效的代码。

2 个答案:

答案 0 :(得分:1)

这是一个带有lapply的基本R方法。

获取data.frames列表

myList <- lapply(seq_along(results), function(i) {
       # get matrix of non NA positions
       pos <- which(!is.na(results[[i]]), arr.ind=TRUE)
       # return data.frame for given list item
       data.frame(x=i,
                  y=paste(rownames(results[[i]])[pos[,1]], colnames(results[[i]])[pos[,2]]),
                  freq=results[[i]][pos])
})

data.frame的第一个变量是lapply迭代的索引。第二种是通过使用非NA位置矩阵粘贴列表中矩阵的rownames和colnames来构造的。第三个变量是使用矩阵子集构造的,其中提取。

然后do.callrbind

do.call(rbind, myList)
   x     y freq
1  1 1B 1A    0
2  1 1C 1A    1
3  1 1D 1A    0
4  1 1C 1B    0
5  1 1D 1B    0
6  1 1D 1C    0
7  2 2B 2A    2
8  2 2C 2A    1
9  2 2D 2A    1
10 2 2C 2B    1
11 2 2D 2B    1
12 2 2D 2C    0
13 3 3B 3A    1

答案 1 :(得分:1)

使用tidyverse

library(tidyverse)
data %>% group_by(region,species) %>% 
  filter(n()>1)%>%
  summarize(y=list(combn(plot,2, paste, collapse="_"))) %>% 
  unnest %>%
  group_by(region,y) %>% 
  summarize(freq=n())

  region     y  freq
   <int> <chr> <int>
1      1 1A_1C     1
2      2 2A_2B     2
3      2 2A_2C     1
4      2 2A_2D     1
5      2 2B_2C     1
6      2 2B_2D     1
7      3 3A_3B     1