前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >30. R 数据整理(五:根据分类新增列的种种方法)

30. R 数据整理(五:根据分类新增列的种种方法)

作者头像
北野茶缸子
发布2021-12-17 09:22:14
6620
发布2021-12-17 09:22:14
举报
文章被收录于专栏:北野茶缸子的专栏

有时候,我们需要对数据框添加新的列,比较常见的场景就是需要根据现有数据框的某列增加新的分类。比如样本分为正常与肿瘤,成绩按照排名区分低、中、高。

比较粗暴的方式当然就是循环了。可是,众所周知,R 不喜欢循环,因此这里总结一些其他的如向量化的处理方法。

这里先创建一个数据框:

代码语言:javascript
复制
> my_d = data.frame(a = sample(30:100, 100, replace = T), b = sample(LETTERS[1:5], 100, replace = T))
> table(my_d$a)

 30  33  35  37  38  39  40  41  42  43  44  46  47  48  49  50  51  54  56  57 
  6   4   2   1   1   4   2   1   4   3   1   1   1   2   2   1   2   1   4   1 
 58  59  60  61  62  63  67  68  70  71  72  73  74  75  76  77  79  80  82  83 
  3   2   3   1   4   3   1   1   1   1   1   2   2   2   1   1   2   1   2   1 
 84  85  87  88  90  91  92  93  94  97  99 100 
  1   2   1   3   4   1   2   1   1   2   1   2 
> table(my_d$b)

 A  B  C  D  E 
21 19 17 16 27 

简单的分类变量

这里主要是针对列的数据为分类变量的,比如样本名等。

  • 逻辑值判断

这个主要针对简单的分类变量,比如需要判断“是否为XX” 或者“结果是否等于XX”这种简单的问题。比如看成绩是否及格:

代码语言:javascript
复制
> my_d[which(my_d$a >= 60), "c"] = "pass"
> !my_d$a >= 60
  [1] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE
 [13] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE
 [25]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE
 [37] FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE
 [49]  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE
 [61]  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE
 [73] FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE
 [85]  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE
 [97]  TRUE FALSE FALSE  TRUE
> my_d[which(!my_d$a >= 60), "c"] = "not pass"
> table(my_d$c)

not pass     pass 
      49       51 

这里which 用于获取逻辑值的下标。

  • ifelse

自认为这个函数比逻辑值要直观很多,但做的也是和逻辑值差不多的是。其可以根据逻辑值的返回结果进行创建等长的向量,分别对应True 与False 的条件:

代码语言:javascript
复制
> head(my_d)
   a b        c
1 73 A     pass
2 48 E not pass
3 30 D not pass
4 75 B     pass
5 79 E     pass
6 61 D     pass
> head(ifelse(my_d$b == "A", 'A group', 'not A group'))
[1] "A group"     "not A group" "not A group" "not A group" "not A group"
[6] "not A group"

相比逻辑值的好处是,其比较直观,而且可以连续的套娃:

代码语言:javascript
复制
> cbind(head(my_d$b),head(ifelse(my_d$b == "A", 'A group', ifelse(my_d$b == 'B', 'B group', "not A& B")))) 
     [,1] [,2]      
[1,] "A"  "A group" 
[2,] "E"  "not A& B"
[3,] "D"  "not A& B"
[4,] "B"  "B group" 
[5,] "E"  "not A& B"
[6,] "D"  "not A& B"

但如果是连续变量或者复杂的分类变量,还是不建议这么玩,毕竟一层套一层的,代码都不好意思给别人看~

  • merge 合并

这种需求其实还是蛮少的。

代码语言:javascript
复制
> my_d2
  b   f
1 A 1st
2 E 2ed
3 D 3rd
4 B 4st
5 C 5st

> head(merge(my_d, my_d2, by = 'b')[sample(1:100, 100),])
   b  a        c   f
91 E 99     pass 2ed
63 D 40 not pass 3rd
34 B 75     pass 4st
67 D 35 not pass 3rd
85 E 74     pass 2ed
84 E 56 not pass 2ed

相对复杂的连续变量

  • cut + pretty/fivenum

cut 用来切割连续性变量,可以将其按照breaks 中的向量区间分割。可以通过labels 参数指定向量,使其元素作为breaks 分割后的新值,ordered_result 默认True,返回有序型因子:

代码语言:javascript
复制
> a
 [1] 80 22 88 54 52 19 65 56 25 99  2 59 79 82 23  7 87 61 49 55
> labels
[1] "差" "中" "良" "好"
> breaks = fivenum(a)
> breaks
[1]  2.0 24.0 55.5 79.5 99.0
b = cut(a, breaks = breaks, labels = labels, include.lowest = T)
> b
 [1] 好 差 好 中 中 差 良 良 中 好 差 良 良 好 差 差 好 良 中 中
Levels: 差 中 良 好
> c = cbind(as.data.frame(a), b)
> head(c)
   a  b
1 80 好
2 22 差
3 88 好
4 54 中
5 52 中
6 19 差

在设置cut 参数的breaks 时,我们除了使用fivenum() 函数获取数值的四分位数,还可以结合pretty 函数,获取指定分段长的数字,pretty 会帮助我们获得等间距的整值:

代码语言:javascript
复制
> pretty(a, 5)
[1]   0  20  40  60  80 100
> labels
[1] "差"   "中"   "良"   "好"   "极好"
> breaks = pretty(a, 5)
b = cut(a, breaks = breaks, labels = labels, include.lowest = T)
> b = cut(a, breaks = breaks, labels = labels, include.lowest = T)
> b
 [1] 好   中   极好 良   良   差   好   良   中   极好 差   良   好   极好 中  
[16] 差   极好 好   良   良  
Levels: 差 中 良 好 极好

使用case_when

相当于高级版的ifelse,就是用起来语法有点怪~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 北野茶缸子 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简单的分类变量
  • 相对复杂的连续变量
  • 使用case_when
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档