在 R 中集成 2 个列表和一个数据框
integrating 2 lists and a data farme in RR
请问我可以用来执行以下操作的 R 代码:
- 我有 2 个 "genome coordinates" 列表:一个列表由代表基因组坐标的数字组成;
假设列表 N
:
n1
n2
n3
n4
和一个列表 M
:
m1
m2
m3
m4
m5
- 和一个数据框
C
,其中对于上面列表中的一些坐标对 (n,m),我们有一个数值强度;
例如:
n1; m1; 100
n1; m2; 300
问题是:我可以使用什么最有效的 R 代码来集成列表 N
、列表 M
和数据框 C
,在为了获得一个数据框:
- 列出
N
作为列名
- 列出
M
作为行名称
N
*M
的单元格中的值,对应数据框C
. 中的数值
一个小例子是:
n1 n2 n3 n4
m1 100 - - -
m2 300 - - -
m3 - - - -
m4 - - - -
m5 - - - -
您可以使用 tidyr
包中的 spread
执行此操作,确保保留出现在两个列表中的所有 n 和 m 值,即使它们没有出现在 C 中:
library(tidyr)
## Replicating the data
listN = list("n1","n2","n3","n4","n5")
listM = list("m1","m2","m3","m4","m5")
C = data.frame(n=c("n1","n2","n3"),m=c("m1","m2","m3"),I=c(100,300,400))
n m I
1 n1 m1 100
2 n2 m2 300
3 n3 m3 400
## Defining factor levels of C using listM and listN, and keeping unused levels when doing the spread
C$n = factor(C$n,levels=unlist(listN))
C$m = factor(C$m,levels=unlist(listM))
res = spread(C,key="n",value="I",drop=F)
这个returns:
m n1 n2 n3 n4 n5
1 m1 100 NA NA NA NA
2 m2 NA 300 NA NA NA
3 m3 NA NA 400 NA NA
4 m4 NA NA NA NA NA
5 m5 NA NA NA NA NA
我相信有人有更简洁的方法来实现以下内容,我很乐意知道。您的数据并未真正准备好 MWE:请参阅 How to make a great R Reproducible Example。但是,给定数据 "as-is" 并假设您真的不想要标题为 'n1' 的第一行。以下解决方案需要 reshape2
包:
N=c('n1','n2','n3','n4')
M=c('m1','m2','m3','m4','m5')
C=data.frame(
X1=c('n1','n1'),
X2=c('m1','m2'),
C=c(100, 300)
)
我们已经定义了上面的数据。现在让我们把它合并在一起。
X = merge(N, M)
让我们在data.frame
中添加NA
s,这样当我们定义项目时它就会被空白。
C$C <- NA
C$C <- C[which(C$X1 %in% N & C$X2 %in% M),'C']
D = merge(N, M, all=TRUE)
names(D) <- c('X1','X2')
names(X) <- c('X1','X2')
E = merge(D, C, all = TRUE, by=c('X1', 'X2'))
library(reshape2)
reshape2::dcast(E, X2 + C ~ X1, drop=FALSE, value.var='C')
希望这对您有所帮助,直到其他人可以更好地解释它。
编辑:因为@Lamia 打败了我,所以我比较了示例的 system.time
值。 . . @Lamia 的答案是在我的机器上重复 10 次后 0.01 +/- 0.032。
我们可以使用索引方法
m1 <- matrix(0, length(listM), length(listN), dimnames = list(unlist(listM), unlist(listN)))
m1[cbind(match(as.character(C$m), rownames(m1)),
match(as.character(C$n), colnames(m1)))] <- C$I
m1
# n1 n2 n3 n4 n5
#m1 100 0 0 0 0
#m2 0 300 0 0 0
#m3 0 0 400 0 0
#m4 0 0 0 0 0
#m5 0 0 0 0 0
数据
listN <- list("n1","n2","n3","n4","n5")
listM <- list("m1","m2","m3","m4","m5")
C <- data.frame(n=c("n1","n2","n3"),m=c("m1","m2","m3"),I=c(100,300,400))
请问我可以用来执行以下操作的 R 代码:
- 我有 2 个 "genome coordinates" 列表:一个列表由代表基因组坐标的数字组成;
假设列表 N
:
n1
n2
n3
n4
和一个列表 M
:
m1
m2
m3
m4
m5
- 和一个数据框
C
,其中对于上面列表中的一些坐标对 (n,m),我们有一个数值强度;
例如:
n1; m1; 100
n1; m2; 300
问题是:我可以使用什么最有效的 R 代码来集成列表 N
、列表 M
和数据框 C
,在为了获得一个数据框:
- 列出
N
作为列名 - 列出
M
作为行名称 N
*M
的单元格中的值,对应数据框C
. 中的数值
一个小例子是:
n1 n2 n3 n4
m1 100 - - -
m2 300 - - -
m3 - - - -
m4 - - - -
m5 - - - -
您可以使用 tidyr
包中的 spread
执行此操作,确保保留出现在两个列表中的所有 n 和 m 值,即使它们没有出现在 C 中:
library(tidyr)
## Replicating the data
listN = list("n1","n2","n3","n4","n5")
listM = list("m1","m2","m3","m4","m5")
C = data.frame(n=c("n1","n2","n3"),m=c("m1","m2","m3"),I=c(100,300,400))
n m I
1 n1 m1 100
2 n2 m2 300
3 n3 m3 400
## Defining factor levels of C using listM and listN, and keeping unused levels when doing the spread
C$n = factor(C$n,levels=unlist(listN))
C$m = factor(C$m,levels=unlist(listM))
res = spread(C,key="n",value="I",drop=F)
这个returns:
m n1 n2 n3 n4 n5
1 m1 100 NA NA NA NA
2 m2 NA 300 NA NA NA
3 m3 NA NA 400 NA NA
4 m4 NA NA NA NA NA
5 m5 NA NA NA NA NA
我相信有人有更简洁的方法来实现以下内容,我很乐意知道。您的数据并未真正准备好 MWE:请参阅 How to make a great R Reproducible Example。但是,给定数据 "as-is" 并假设您真的不想要标题为 'n1' 的第一行。以下解决方案需要 reshape2
包:
N=c('n1','n2','n3','n4')
M=c('m1','m2','m3','m4','m5')
C=data.frame(
X1=c('n1','n1'),
X2=c('m1','m2'),
C=c(100, 300)
)
我们已经定义了上面的数据。现在让我们把它合并在一起。
X = merge(N, M)
让我们在data.frame
中添加NA
s,这样当我们定义项目时它就会被空白。
C$C <- NA
C$C <- C[which(C$X1 %in% N & C$X2 %in% M),'C']
D = merge(N, M, all=TRUE)
names(D) <- c('X1','X2')
names(X) <- c('X1','X2')
E = merge(D, C, all = TRUE, by=c('X1', 'X2'))
library(reshape2)
reshape2::dcast(E, X2 + C ~ X1, drop=FALSE, value.var='C')
希望这对您有所帮助,直到其他人可以更好地解释它。
编辑:因为@Lamia 打败了我,所以我比较了示例的 system.time
值。 . . @Lamia 的答案是在我的机器上重复 10 次后 0.01 +/- 0.032。
我们可以使用索引方法
m1 <- matrix(0, length(listM), length(listN), dimnames = list(unlist(listM), unlist(listN)))
m1[cbind(match(as.character(C$m), rownames(m1)),
match(as.character(C$n), colnames(m1)))] <- C$I
m1
# n1 n2 n3 n4 n5
#m1 100 0 0 0 0
#m2 0 300 0 0 0
#m3 0 0 400 0 0
#m4 0 0 0 0 0
#m5 0 0 0 0 0
数据
listN <- list("n1","n2","n3","n4","n5")
listM <- list("m1","m2","m3","m4","m5")
C <- data.frame(n=c("n1","n2","n3"),m=c("m1","m2","m3"),I=c(100,300,400))