Q&A:在melt和dcast之间反复横跳

2022-04-14 12:01:55 浏览数 (1)

Q&A:在meltdcast之间反复横跳

写在前面

各位水友大家好,自从上一次发布了改版的推文说明之后,大喵和村长收到了很多水友的问题,我们也对这些问题进行了回复,希望能对大家R语言的学习有所帮助,在此先谢谢各位的支持!本期我们精心挑选了一位水友遇到的问题进行知识分享,希望大家踊跃提问,在此再次谢过了!

收到的问题

首先感谢我不是黄欢乐的提问。在处理数据的过程中可能会遇到这种情况:许多数据记录存在横向和纵向不明确的情况。在如下数据集中,第1个姓名id横向呈现了3次用药记录,第2个姓名id在纵向呈现了4次用药记录,且存在两次空记录。

代码语言:javascript复制
library(data.table)
data <- fread("data.txt", encoding = "UTF-8", na.string = "")
data[1:5]

姓名

用药名称1

用法1

用量1

服药时间1

用药依从性1

用药名称2

用法2

用量2

服药时间2

用药依从性2

用药名称3

用法3

用量3

服药时间3

用药依从性3

梁小妹

缬沙坦胶囊

口服

80mg/qd

1年

规律

甲磺酸氨氯地平片

口服

5mg/qd

1年

规律

阿司匹林肠溶片

口服

100mg/qd

1年

规律

郑浮昌

厄贝沙坦

口服,每日1次。

150mg

1年

规律

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

郑浮昌

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

郑浮昌

硫酸氢氯比格雷片

口服,每日1次。

25mg

1年

规律

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

郑浮昌

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

NA

最终对数据集的清洗结果:需要使得每个姓名id只存在一行记录,所有的记录横向排列,并且需要删除所有的含NA记录的项。

问题解决

我们照惯例先把这段代码优雅的放上来,再细细解读:

代码语言:javascript复制
data <- data[, melt(.SD, measure = patterns("^用药名称", "^用法", "^用量", "^服药时间", "^用药依从性"), value.name = c("用药名称", "用法", "用量", "服药时间", "用药依从性"))]
data <- data[rowMeans(!is.na(data[, 3:7])) == 1, .SD
    ][, variable := 1:.N, by = .(`姓名`)
    ][, dcast(.SD, `姓名` ~ variable, value.var = c("用药名称", "用法", "用量", "服药时间", "用药依从性"))]
data

姓名

用药名称_1

用药名称_2

用药名称_3

用法_1

用法_2

用法_3

用量_1

用量_2

用量_3

服药时间_1

服药时间_2

服药时间_3

用药依从性_1

用药依从性_2

用药依从性_3

叶桃芳

安耐喜

NA

NA

口服

NA

NA

qd,1粒

NA

NA

1年

NA

NA

规律

NA

NA

庞燕改

厄贝沙坦

硫酸氢氯比格雷片

珍菊降压片

口服,每日1次。

口服,每日1次。

口服,每日1次。

150mg

25mg

1片

1年

1年

1年

规律

规律

规律

林丽芳

福辛普利钠片

NA

NA

口服

NA

NA

10mg

NA

NA

1年

NA

NA

规律

NA

NA

梁小妹

缬沙坦胶囊

甲磺酸氨氯地平片

阿司匹林肠溶片

口服

口服

口服

80mg/qd

5mg/qd

100mg/qd

1年

1年

1年

规律

规律

规律

罗秀丽

甲磺酸氨氯地平片

NA

NA

口服

NA

NA

1粒 qd

NA

NA

1年

NA

NA

规律

NA

NA

郑浮昌

厄贝沙坦

硫酸氢氯比格雷片

珍菊降压片

口服,每日1次。

口服,每日1次。

口服,每日1次。

150mg

25mg

1片

1年

1年

1年

规律

规律

规律

黄舜

盐酸吡格列酮(卡司平)

NA

NA

口服

NA

NA

2片qd

NA

NA

1年

NA

NA

规律

NA

NA

代码解读

首先来看第一部分代码:

代码语言:javascript复制
data <- data[, melt(.SD, measure = patterns("^用药名称", "^用法", "^用量", "^服药时间", "^用药依从性"), value.name = c("用药名称", "用法", "用量", "服药时间", "用药依从性"))]
data[1:5]

姓名

variable

用药名称

用法

用量

服药时间

用药依从性

梁小妹

1

缬沙坦胶囊

口服

80mg/qd

1年

规律

郑浮昌

1

厄贝沙坦

口服,每日1次。

150mg

1年

规律

郑浮昌

1

NA

NA

NA

NA

NA

郑浮昌

1

硫酸氢氯比格雷片

口服,每日1次。

25mg

1年

规律

郑浮昌

1

NA

NA

NA

NA

NA

在这里我们利用了melt这样一个函数。利用这个函数的目的在于,在data.table中进行数据处理贯彻的是向量思维

这也是R语言和Python语言进行数据处理的底层逻辑。从数据特点的角度来解释,也即是长表优于宽表。 ”

有鉴于此,必须首先想办法把变量减少,使得宽表变成长表,而更有利于之后的操作。

通过使用melt能够达到这一效果,在这里使用了melt中的measure选项,通过patterns进行了关于变量名的正则匹配,将五类同属性变量("^用药名称", "^用法", "^用量", "^服药时间", "^用药依从性")进行合并;并最终通过value.name的选项对五个统一后的变量进行重命名。

第二部分代码我们分成两部分来看:

代码语言:javascript复制
data <- data[rowMeans(!is.na(data[, 3:7])) == 1, .SD
    ][, variable := 1:.N, by = .(`姓名`)]
data[1:5]

姓名

variable

用药名称

用法

用量

服药时间

用药依从性

梁小妹

1

缬沙坦胶囊

口服

80mg/qd

1年

规律

郑浮昌

1

厄贝沙坦

口服,每日1次。

150mg

1年

规律

郑浮昌

2

硫酸氢氯比格雷片

口服,每日1次。

25mg

1年

规律

郑浮昌

3

珍菊降压片

口服,每日1次。

1片

1年

规律

黄舜

1

盐酸吡格列酮(卡司平)

口服

2片qd

1年

规律

这一部分代码极为重要,首先利用rowMeans进行行筛选,为的是将原本就缺失的记录,以及在宽表到长表转换中生成的缺失记录进行删除。这就是源于数据的横向与纵向记录规则不明确导致的,在两个方向都可能会存在缺失值。在进行宽表到长表的转化过程中,这样的缺失值同样会保留下来。因此要对数据进行该操作。此外关于函数筛选的用法,这里不进行阐述,关于这内容的详细解读可参考R语言:以多列标准筛选特定行

此外对variable这个变量进行了更改。由于之后需要将长表变成宽表,因此需要对每一个姓名id的所有不同记录进行编号。可以发现经过melt之后的数据,编号依据是曾经的观测记录。现在数据的观测记录发生了改变,因此需要对观测记录进行重新编号。在这里利用了1:.N进行by的分组编号。

最后一部分代码则为melt的逆操作:

代码语言:javascript复制
data <- data[, dcast(.SD, `姓名` ~ variable, value.var = c("用药名称", "用法", "用量", "服药时间", "用药依从性"))]
data

姓名

用药名称_1

用药名称_2

用药名称_3

用法_1

用法_2

用法_3

用量_1

用量_2

用量_3

服药时间_1

服药时间_2

服药时间_3

用药依从性_1

用药依从性_2

用药依从性_3

叶桃芳

安耐喜

NA

NA

口服

NA

NA

qd,1粒

NA

NA

1年

NA

NA

规律

NA

NA

庞燕改

厄贝沙坦

硫酸氢氯比格雷片

珍菊降压片

口服,每日1次。

口服,每日1次。

口服,每日1次。

150mg

25mg

1片

1年

1年

1年

规律

规律

规律

林丽芳

福辛普利钠片

NA

NA

口服

NA

NA

10mg

NA

NA

1年

NA

NA

规律

NA

NA

梁小妹

缬沙坦胶囊

甲磺酸氨氯地平片

阿司匹林肠溶片

口服

口服

口服

80mg/qd

5mg/qd

100mg/qd

1年

1年

1年

规律

规律

规律

罗秀丽

甲磺酸氨氯地平片

NA

NA

口服

NA

NA

1粒 qd

NA

NA

1年

NA

NA

规律

NA

NA

郑浮昌

厄贝沙坦

硫酸氢氯比格雷片

珍菊降压片

口服,每日1次。

口服,每日1次。

口服,每日1次。

150mg

25mg

1片

1年

1年

1年

规律

规律

规律

黄舜

盐酸吡格列酮(卡司平)

NA

NA

口服

NA

NA

2片qd

NA

NA

1年

NA

NA

规律

NA

NA

在运用dcast时,~左边的变量为表更改结构以后体现记录识别唯一性primary key~右边的变量为数据变宽之后同类记录的序号variablevalue.var中的变量名与~右边变量中记录的序号整合在一起生成一系列的同类变量,最终得到我们想要的结果。

总结

该问题最主要考察了对数据结构的理解,如何在记录规则混乱的情况下,进行数据结构化处理。长表和宽表之间的相互转换,有时会在数据清洗中用到,对meltdcast两个函数的理解需要深入。

na

0 人点赞