我有一个数据框:
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
我并不反对将第一个/原始数据帧转换为此输出数据帧以绕过循环和矩阵列表的更有效的代码。
答案 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.call
与rbind
。
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