用 R 填充长格式的不完整相关矩阵
fill an incomplete correlation matrix in long format with R
我有一个不完整的长格式方阵,我想用 ggplot2::geom_raster 填充它。假设这是一个相关矩阵,其值 (z) 的范围为 0 到 1。
df <- data.frame(x=LETTERS[1:3], y=LETTERS[c(3,1,2)], z=c(0,1,-1))
df
输出为
x y z
1 A C 0
2 B A 1
3 C B -1
我能完成:
library(tidyr)
complete(df,x , y, fill=list(z=NA))
# A tibble: 9 x 3
x y z
<fctr> <fctr> <dbl>
1 A A NA
2 A B NA
3 A C 0
4 B A 1
5 B B NA
6 B C NA
7 C A NA
8 C B -1
9 C C NA
现在,因为它应该是一个相关矩阵,所以我想填充它,如果我知道 cor(D,A) 那么我应该以 cor(A,D) == cor( D,A).因此,预期结果将是:
# A tibble: 9 x 3
x y z
<fctr> <fctr> <dbl>
1 A A NA
2 A B 1
3 A C 0
4 B A 1
5 B B NA
6 B C -1
7 C A 0
8 C B -1
9 C C NA
我可以做复杂的事情,但也许有一个简单的解决方案...
谢谢
使用 tidyverse
的解决方案。请注意,我在操作前将所有因子列更改为字符。 df2
是最终输出。
library(tidyverse)
df2 <- df %>%
complete(x, y) %>%
mutate(Group = map2_chr(x, y, ~paste0(sort(c(.x, .y)), collapse = "_"))) %>%
group_by(Group) %>%
mutate(z = mean(z, na.rm = TRUE)) %>%
ungroup() %>%
select(-Group)
df2
# # A tibble: 9 x 3
# x y z
# <chr> <chr> <dbl>
# 1 A A NaN
# 2 A B 1
# 3 A C 0
# 4 B A 1
# 5 B B NaN
# 6 B C -1
# 7 C A 0
# 8 C B -1
# 9 C C NaN
数据
df <- data.frame(x=LETTERS[1:3], y=LETTERS[c(3,1,2)], z=c(0,1,-1),
stringsAsFactors = FALSE)
我有一个 data.table 解决方案,使用不同的技术。
library(data.table)
df2 <- complete(df,x , y, fill=list(z=NA))
df2 <- setDT(df2)
df2[!is.na(z),.(x = y, y = x, z = z)][df2, on = .(x,y)][is.na(z),z:=i.z][,i.z := NULL][]
x y z
1: A A NA
2: A B 1
3: A C 0
4: B A 1
5: B B NA
6: B C -1
7: C A 0
8: C B -1
9: C C NA
它的作用:它将 df2 与
合并
df2[!is.na(z),.(x = y, y = x, z = z)]
x y z
1: C A 0
2: A B 1
3: B C -1
这是非相关值,但 x 和 y 已切换。结果是
x y z i.z
1: A A NA NA
2: A B 1 NA
3: A C NA 0
4: B A NA 1
5: B B NA NA
6: B C -1 NA
7: C A 0 NA
8: C B NA -1
9: C C NA NA
然后我用 i.z 值完成 z,并取消 i.z 列。使用 merge
的另一种语法:
merge(df2[!is.na(z),.(x = y, y = x, z = z)],df2,all.y = T,by = c("x","y"))[,z:=ifelse(is.na(z.x),z.y,z.x)][,c("z.x","z.y"):=NULL][]
与dplyr相同的想法:
library(dplyr)
right_join(df2 %>%
filter(!is.na(z)) %>%
rename(x = y, y = x),
df2, by = c("x","y")) %>%
mutate(z = ifelse(is.na(z.x),z.y,z.x)) %>%
select(y,x,z)
y x z
1 A A NA
2 B A 1
3 C A 0
4 A B 1
5 B B NA
6 C B -1
7 A C 0
8 B C -1
9 C C NA
我有一个不完整的长格式方阵,我想用 ggplot2::geom_raster 填充它。假设这是一个相关矩阵,其值 (z) 的范围为 0 到 1。
df <- data.frame(x=LETTERS[1:3], y=LETTERS[c(3,1,2)], z=c(0,1,-1))
df
输出为
x y z
1 A C 0
2 B A 1
3 C B -1
我能完成:
library(tidyr)
complete(df,x , y, fill=list(z=NA))
# A tibble: 9 x 3
x y z
<fctr> <fctr> <dbl>
1 A A NA
2 A B NA
3 A C 0
4 B A 1
5 B B NA
6 B C NA
7 C A NA
8 C B -1
9 C C NA
现在,因为它应该是一个相关矩阵,所以我想填充它,如果我知道 cor(D,A) 那么我应该以 cor(A,D) == cor( D,A).因此,预期结果将是:
# A tibble: 9 x 3
x y z
<fctr> <fctr> <dbl>
1 A A NA
2 A B 1
3 A C 0
4 B A 1
5 B B NA
6 B C -1
7 C A 0
8 C B -1
9 C C NA
我可以做复杂的事情,但也许有一个简单的解决方案...
谢谢
使用 tidyverse
的解决方案。请注意,我在操作前将所有因子列更改为字符。 df2
是最终输出。
library(tidyverse)
df2 <- df %>%
complete(x, y) %>%
mutate(Group = map2_chr(x, y, ~paste0(sort(c(.x, .y)), collapse = "_"))) %>%
group_by(Group) %>%
mutate(z = mean(z, na.rm = TRUE)) %>%
ungroup() %>%
select(-Group)
df2
# # A tibble: 9 x 3
# x y z
# <chr> <chr> <dbl>
# 1 A A NaN
# 2 A B 1
# 3 A C 0
# 4 B A 1
# 5 B B NaN
# 6 B C -1
# 7 C A 0
# 8 C B -1
# 9 C C NaN
数据
df <- data.frame(x=LETTERS[1:3], y=LETTERS[c(3,1,2)], z=c(0,1,-1),
stringsAsFactors = FALSE)
我有一个 data.table 解决方案,使用不同的技术。
library(data.table)
df2 <- complete(df,x , y, fill=list(z=NA))
df2 <- setDT(df2)
df2[!is.na(z),.(x = y, y = x, z = z)][df2, on = .(x,y)][is.na(z),z:=i.z][,i.z := NULL][]
x y z
1: A A NA
2: A B 1
3: A C 0
4: B A 1
5: B B NA
6: B C -1
7: C A 0
8: C B -1
9: C C NA
它的作用:它将 df2 与
合并df2[!is.na(z),.(x = y, y = x, z = z)]
x y z
1: C A 0
2: A B 1
3: B C -1
这是非相关值,但 x 和 y 已切换。结果是
x y z i.z
1: A A NA NA
2: A B 1 NA
3: A C NA 0
4: B A NA 1
5: B B NA NA
6: B C -1 NA
7: C A 0 NA
8: C B NA -1
9: C C NA NA
然后我用 i.z 值完成 z,并取消 i.z 列。使用 merge
的另一种语法:
merge(df2[!is.na(z),.(x = y, y = x, z = z)],df2,all.y = T,by = c("x","y"))[,z:=ifelse(is.na(z.x),z.y,z.x)][,c("z.x","z.y"):=NULL][]
与dplyr相同的想法:
library(dplyr)
right_join(df2 %>%
filter(!is.na(z)) %>%
rename(x = y, y = x),
df2, by = c("x","y")) %>%
mutate(z = ifelse(is.na(z.x),z.y,z.x)) %>%
select(y,x,z)
y x z
1 A A NA
2 B A 1
3 C A 0
4 A B 1
5 B B NA
6 C B -1
7 A C 0
8 B C -1
9 C C NA