R不规则数据长变宽

2023-02-27 20:56:14 浏览数 (1)

交流群看到小伙伴提问:有一个数据,大概如下所示 :

代码语言:javascript复制
a a b a c a b c c c a
1 3 3 3 2 5 7 2 1 9 8

想要转换为如下格式:

代码语言:javascript复制
a b c
1 3 2
3 3 2
3   1
5   9
8

我看了看,大概是提问的小伙伴自己没搞清楚自己想要什么,他自己给出来了一个非常丑陋的解决方案, 他实现如下:

代码语言:javascript复制
#生成长度不等的list (猜测可以直接生成最长长度的data.frame,只是差的值用NA代替)
df<-list()
for (i in unique(row.names(TPM_mtx_filter_asMtx))) {
df[i]<-list(TPM_mtx_filter_asMtx[row.names(TPM_mtx_filter_asMtx)==i,])
}
#将list转换为等长dataframe
df_dataFrame<-as.data.frame(sapply(df, "[", i = 1:max(sapply(df, length))))
#存为文件:
write.csv(df_dataFrame,file = 'Lrrc4/time_all_split.csv',quote = F,row.names = F,na = '')

其实我明白他想要什么,理论上很简单的代码,就是 split 函数而已 :

代码语言:javascript复制
test = data.frame(
x = strsplit(x = c("aabacabccca"),split = "")[[1]],
y = strsplit(x = c("13332572198"),split = "")[[1]]
)

split(test$y,test$x)

就可以得到如下所示的列表啦 :

代码语言:javascript复制
$a
[1] "1" "3" "3" "5" "8"

$b
[1] "3" "7"

$c
[1] "2" "2" "1" "9"

但是提问的小伙伴把需求搞复杂了,生成了列表之后一定要变成数据框,而且很明显这个列表里面的元素不等长,强行变成数据框肯定是会需要空格补全NA,代码胡很复杂。恰好群里的小伙伴给出来了极致的优雅代码:

代码语言:javascript复制
library(tidyr)
library(dplyr)

test %>%
group_by(x) %>%
mutate(id = row_number()) %>%
spread(x, y) %>%
select(-id)

得到,如下所示:

代码语言:javascript复制
# A tibble: 5 × 3
  a     b     c    
  <chr> <chr> <chr>
1 1     3     2    
2 3     7     2    
3 3     NA    1    
4 5     NA    9    
5 8     NA    NA   

看样子R语言编程技能也是学无止境啦。

R语言不仅在生物信息数(主要体现在bioconductor系列包)据处理中发挥着重要作用,其实也是其他主流数据处理人士(包括互联网,金融,游戏行业)的首选工具。所以基本上找到我来咨询如何入门生物信息学的,我都是推荐他必须学的就是R。但是实际上呢,我作为老一辈的生信工程师,所以喜欢perl一点,排斥python,我也稍微看过一些python的语法,个人认为R和python呢almostly 几乎 一模一样的。R的特点就是内置了大量的函数,基本上你认识的英文单词都可以是一个函数,即使不是,你也可以自定义为函数。搞清楚了函数和变量,就可以看懂大部分的R代码了。通常我给初学者的知识点路线图如下:

  • 了解常量和变量概念
  • 加减乘除等运算(计算器)
  • 多种数据类型(数值,字符,逻辑,因子)
  • 多种数据结构(向量,矩阵,数组,数据框,列表)
  • 文件读取和写出
  • 简单统计可视化
  • 无限量函数学习

详见:《生信分析人员如何系统入门R(2019更新版)》, 也可以看B站我的R视频:

0 人点赞