我有一个数据框:
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
我不反对将第一个/原始数据帧转换为此输出数据帧以绕过循环和矩阵列表的更高效代码。
最佳答案
这是一个带有 lapply
的基本 R 方法。
获取数据帧列表
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 位置矩阵将矩阵的行名和列名粘贴到列表中来构建的。第三个变量是使用提取的矩阵子集构造的。
然后使用rbind
do.call
。
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
关于r - 将矩阵列表转换为单个数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44728704/