R 具有因子水平的双色热图

R 具有因子水平的双色热图,r,ggplot2,dplyr,tidyverse,R,Ggplot2,Dplyr,Tidyverse,我有这个数据框: set.seed(0) df <- data.frame(id = factor(sample(1:100, 10000, replace=TRUE), levels=1:100), year = factor(sample(1950:2019, 10000, replace=TRUE), levels=1950:2019)) %>% unique() %>% arrange(id, year) 将这两个变量绘制为因子的目的是绘制它们,即

我有这个数据框:

set.seed(0)
df <- data.frame(id = factor(sample(1:100, 10000, replace=TRUE), levels=1:100),
          year = factor(sample(1950:2019, 10000, replace=TRUE), levels=1950:2019)) %>% unique() %>% arrange(id, year)
将这两个变量绘制为因子的目的是绘制它们,即使某一年没有任何id(并将整行绘制为红色)

编辑

有两件事我忘了补充(希望不会太晚):

  • 如何将alpha透明度添加到
    geom_tile()
    ,而不会弄乱它
  • 我需要将ID从最大丢失到最小丢失进行排序

我认为您需要在绘图之前进行一些预处理。创建一个临时变量(
data\u exist
),表示该
id
年份的数据存在。然后使用
complete
为每个
id
填充缺少的
年份
,并绘制它

library(tidyverse)
df %>%
   mutate_all(~as.integer(as.character(.))) %>%
   mutate(data_exist = 1) %>%
   complete(id, year = min(year):max(year), fill = list(data_exist = 0)) %>%
   mutate(data_exist = factor(data_exist)) %>%
   ggplot() + aes(id, year, fill= data_exist) + geom_tile()

tidyr软件包中的
complete()
函数用于填充缺少的组合。首先,您需要设置一个标志变量来指示数据是否存在,然后用缺少的组合展开数据框,并用0填充新的标志变量:

df <- df %>% 
  mutate(flag = TRUE) %>% 
  complete(id, year, fill = list(flag = FALSE))

ggplot(df, aes(id, year, fill = flag)) + 
  geom_tile()

使用
expand.grid
您可以创建一个包含所有ID和年份组合的数据框,然后左键连接这些组合,查看是否在
df

  all <- expand.grid(id=levels(df$id),year=levels(df$year)) %>% 
              left_join(df) %>% 
              mutate(present=ifelse(is.na(present),'0','1'))
   ggplot(all, aes(as.numeric(id), as.numeric(year), fill= present)) + 
            geom_tile() + 
            scale_fill_manual(values=c('0'='red','1'='blue')) + # change default colors
            theme(legend.position="None") # hide legend
all%
左联合(df)%>%
突变(present=ifelse(is.na(present),'0','1'))
ggplot(全部,aes(作为数字(id),作为数字(年份),填充=存在))+
geom_tile()+
缩放填充手动(值=c('0'='red','1'='blue'))+#更改默认颜色
主题(legend.position=“None”)#隐藏图例

好极了!有什么办法可以分类吗?例如,将ID从FALSE的最大计数排序到最小计数?我在
complete()
函数之后尝试了
arrange()
,但似乎我必须更改因子级别顺序才能做到这一点,有没有更简单的方法?。此外,您能否解释一下R在
fill=list(flag=FALSE)
中是如何思考/工作的?为什么要将其转换为列表?@Chris,显示的数据只有1s和0s。如果您想查看每个id有多少个,请使用
df%>%groupby(id)%>%summary(sum=sum(flag))
。@Chris
complete()
需要一个
fill
参数列表,因为可能有多个变量需要输入默认值,而不是
NA
。感谢您回答@Phil!。我遇到的主要问题是如何在代码中集成
df%>%groupby(id)%>%summary(sum=sum(flag))
,而不将另一个对象分配给变量?假设我总是尝试用一次代码绘制图,就像示例一样(以节省内存并获得干净的代码)@Chris我编辑了上面的答案来回答其他两个问题。
# Determine the order of the IDs
df_order <- df %>% 
  group_by(id) %>% 
  summarize(sum = sum(flag)) %>% 
  arrange(desc(sum)) %>% 
  mutate(order = row_number()) %>% 
  select(id, order)

# Set the IDs in order on the chart
df <- df %>% 
  left_join(df_order) %>% 
  mutate(id = fct_reorder(id, order))
  all <- expand.grid(id=levels(df$id),year=levels(df$year)) %>% 
              left_join(df) %>% 
              mutate(present=ifelse(is.na(present),'0','1'))
   ggplot(all, aes(as.numeric(id), as.numeric(year), fill= present)) + 
            geom_tile() + 
            scale_fill_manual(values=c('0'='red','1'='blue')) + # change default colors
            theme(legend.position="None") # hide legend