代码语言: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视频: