R语言 | 宽数据变成一列,保留对应的行名和列名

对应稀疏矩阵 转为 宽数据框,见

目的:比如查看鸢尾花整体的指标分布,4个指标分开,画到一个图中。每个品种画一个图。

1.数据整理:宽变长 手工版

dat0=iris
dat=unlist(dat0[,1:4]) |> as.data.frame()
colnames(dat)="val"
dim(dat) #600 1

dat$obs= rep( rownames(dat0), times=ncol(dat0[,1:4]) )
dat$variation= rep( colnames(dat0[,1:4]), each=nrow(dat0[,1:4]) )
dat$Species= rep( dat0$Species, times=ncol(dat0[,1:4]) )
dim(dat) # 600   4
head(dat)
#                        val obs    variation Species
#Sepal.Length1 5.1   1 Sepal.Length  setosa
#Sepal.Length2 4.9   2 Sepal.Length  setosa

(2) 函数实现: wide2long()

#' data.frame wide to long
#'
#' @param dat wide df
#' @param keep colnames want to keep
#'
#' @return long df
#' @export
#'
#' @examples
wide2long=function(dat, keep=NULL){
  col.name = colnames(dat)
  if(!is.null(keep)){
    col.name = setdiff(colnames(dat), keep)
  }
  dat2=dat[, col.name, drop=F]
  #
  result = data.frame(
    val= unlist(dat2), #按列展开数据框
    obs= rep( rownames(dat2), times=ncol(dat2) ), #row as obs
    variation= rep( colnames(dat2), each=nrow(dat) ) #col as variables
  )
  
  if(!is.null(keep)){
    for(ele in keep){
      result[, ele]=rep( dat[, ele], times=ncol(dat2) )
    }
  }
  
  return(result)
}
if(0){
  t1=wide2long(iris, c("Species") )
  dim(t1)
  head(t1)
  tail(t1)
  #               val obs   variation   Species
  #Petal.Width145 2.5 145 Petal.Width virginica
  #Petal.Width146 2.3 146 Petal.Width virginica
}

2.画图

colorset.types=ggsci::pal_npg()(5)[c(1,2,4,5)]
scales::show_col(colorset.types)
library(ggplot2)
ggplot(dat, aes(val, fill=variation))+ #也可以输入1(2)中的t1,等价
  geom_density(linewidth=1, alpha=0.5)+
  facet_grid(Species~., scale="free_y")+
  theme_bw(base_size = 14)+
  scale_fill_manual("Species", values = colorset.types, #breaks = my.breaks, labels=my.labels
                    )+
  #scale_x_discrete(breaks = my.breaks, labels = my.labels) +
  labs(x="Length")

在这里插入图片描述

3. 原理

原理1:rep() 重复的方式,整体重复times=,每个元素分别重复 each=

rep(c("a", "b"), times=2) #"a" "b" "a" "b"
rep(c("a", "b"), each=2) #"a" "a" "b" "b"

原理2: 对数据框做 unlist() 默认是按列展开。
数学中矩阵是列向量。

> head(iris[1:2, 1:4])
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1          5.1         3.5          1.4         0.2
2          4.9         3.0          1.4         0.2
> unlist(iris[1:2, 1:4])
Sepal.Length1 Sepal.Length2  Sepal.Width1  Sepal.Width2 Petal.Length1 Petal.Length2  Petal.Width1  Petal.Width2 
          5.1           4.9           3.5           3.0           1.4           1.4           0.2           0.2 

End.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值