= dcast(DT.m, ...~ variable, value.var = c("dob"))
- DT.c DT.c
= dcast(DT.m, ...~ variable, value.var = c("dob"))
+ DT.c DT.c
Key: <family_id, age_mother, gender_child1, gender_child2, gender_child3>
family_id age_mother gender_child1 gender_child2 gender_child3 dob_child1
@@ -1265,10 +1275,10 @@ <
这里我们要还原的列为variable,而值放在dob列中,其他变量则统统用...
来表示。我们看到这个函数的第二个参数必须要用方程式来表示。 下面我们同时进行两个转换(dob和gender)。知道单个转化如何进行,多个的话,只要在后面加一个变量即可。
= paste0("dob_child", 1:3)
- colA = paste0("gender_child", 1:3)
- colB = melt(DT, measure.vars = list(colA, colB), value.name = c("dob", "gender"))
- DT.m2 DT.m2
= paste0("dob_child", 1:3)
+ colA = paste0("gender_child", 1:3)
+ colB = melt(DT, measure.vars = list(colA, colB), value.name = c("dob", "gender"))
+ DT.m2 DT.m2
family_id age_mother variable dob gender
<int> <int> <fctr> <IDat> <int>
@@ -1291,8 +1301,8 @@ <
它的逆运算也非常简便:
= dcast(DT.m2, family_id + age_mother ~ variable, value.var = c("dob", "gender"))
- DT.c2 DT.c2
= dcast(DT.m2, family_id + age_mother ~ variable, value.var = c("dob", "gender"))
+ DT.c2 DT.c2
Key: <family_id, age_mother>
family_id age_mother dob_1 dob_2 dob_3 gender_1 gender_2
@@ -1313,8 +1323,8 @@ <
有一个小问题就是,总是需要构造变量名称,然后放在colA和colB中,这样不是特别方便。我们可以用pattern函数来识别列名称的模式,从而简化这个工作:
= melt(DT, measure.vars = patterns("^dob", "^gender"), value.name = c("dob", "gender"))
- DT.m2 DT.m2
= melt(DT, measure.vars = patterns("^dob", "^gender"), value.name = c("dob", "gender"))
+ DT.m2 DT.m2
family_id age_mother variable dob gender
<int> <int> <fctr> <IDat> <int>
@@ -1357,28 +1367,28 @@ 5.3.2.1.1 检索
检索是针对用户的需求,来提取总数据集一部分进行查阅,一般可以分为行检索与列检索。 在行检索中,一般是根据数据条目所在位置进行检索。比如我们想要查看iris数据表的第3行,可以这样操作:
-library(pacman)
-p_load(tidyfst)
-
-%>% slice_dt(3) iris
+library(pacman)
+p_load(tidyfst)
+
+%>% slice_dt(3) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
1: 4.7 3.2 1.3 0.2 setosa
-如果想要查看多列,可以使用向量作为检索内容。
+如果想要查看多行,可以使用向量作为检索内容。
-# 查看第4和第6列
-%>% slice_dt(c(4,6)) iris
+# 查看第4和第6行
+%>% slice_dt(c(4,6)) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
1: 4.6 3.1 1.5 0.2 setosa
2: 5.4 3.9 1.7 0.4 setosa
-# 查看第4到第6列
-%>% slice_dt(4:6) iris
+# 查看第4到第6行
+%>% slice_dt(4:6) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1389,8 +1399,8 @@
对列进行检索,则具有更多灵活的选择。首先,与行检索类似,可以根据列所在的位置,来对列进行检索。
-# 查看第1列
-%>% select_dt(1) iris
+# 查看第1列
+%>% select_dt(1) iris
Sepal.Length
<num>
@@ -1400,8 +1410,8 @@
-# 查看第1和第3列
-%>% select_dt(1,3) iris
+# 查看第1和第3列
+%>% select_dt(1,3) iris
Sepal.Length Petal.Length
<num> <num>
@@ -1411,8 +1421,8 @@
-# 查看第1到3列
-%>% select_dt(1:3) iris
+# 查看第1到3列
+%>% select_dt(1:3) iris
Sepal.Length Sepal.Width Petal.Length
<num> <num> <num>
@@ -1425,8 +1435,8 @@
其次,还可以通过变量的名称,直接对其中的一个或多个变量进行检索。
-# 选择Species列
-%>% select_dt(Species) iris
+# 选择Species列
+%>% select_dt(Species) iris
Species
<fctr>
@@ -1436,8 +1446,8 @@
-# 选择Sepal.Length和Sepal.Width列
-%>% select_dt(Sepal.Length,Sepal.Width) iris
+# 选择Sepal.Length和Sepal.Width列
+%>% select_dt(Sepal.Length,Sepal.Width) iris
Sepal.Length Sepal.Width
<num> <num>
@@ -1447,8 +1457,8 @@
-# 选择从Sepal.Length列到Petal.Length列中的所有列
-%>% select_dt(Sepal.Length:Petal.Length) iris
+# 选择从Sepal.Length列到Petal.Length列中的所有列
+%>% select_dt(Sepal.Length:Petal.Length) iris
Sepal.Length Sepal.Width Petal.Length
<num> <num> <num>
@@ -1461,7 +1471,7 @@
如果要按照名称选择多列,还可以使用正则表达式的方法。比如我们要选择列名称中包含“Pe”的列,可以这样操作:
-%>% select_dt("Pe") iris
+%>% select_dt("Pe") iris
Petal.Length Petal.Width
<num> <num>
@@ -1474,7 +1484,7 @@
与此同时,我们还可以根据数据类型来选择列,比如我们如果需要选择所有的因子变量,可以这样操作:
-%>% select_dt(is.factor) iris
+%>% select_dt(is.factor) iris
Species
<fctr>
@@ -1487,8 +1497,8 @@
如果要去除某些列,在前面加负号(“-“)即可:
-# 去除Sepal.Length列
-%>% select_dt(-Sepal.Length) iris
+# 去除Sepal.Length列
+%>% select_dt(-Sepal.Length) iris
Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <fctr>
@@ -1498,8 +1508,8 @@
-# 去除第1列
-%>% select_dt(-1) iris
+# 去除第1列
+%>% select_dt(-1) iris
Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <fctr>
@@ -1509,8 +1519,8 @@
-# 去除列名称包含“Se”的列
-%>% select_dt(-"Se") iris
+# 去除列名称包含“Se”的列
+%>% select_dt(-"Se") iris
Petal.Length Petal.Width Species
<num> <num> <fctr>
@@ -1520,8 +1530,8 @@
-# 去除数据类型为因子型的列
-%>% select_dt(-is.factor) iris
+# 去除数据类型为因子型的列
+%>% select_dt(-is.factor) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width
<num> <num> <num> <num>
@@ -1537,7 +1547,7 @@ 5.3.2.1.2 筛选
筛选操作就是要把数据框中符合条件的行筛选出来,在tidyfst包中可以使用filter_dt
函数进行实现。比如我们要筛选iris数据框中Sepal.Length列大于7的条目,可以这样操作:
-%>% filter_dt(Sepal.Length > 7) iris
+%>% filter_dt(Sepal.Length > 7) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1557,7 +1567,7 @@
在筛选条件中,可以使用且(&)、或(|)和非(!)三种逻辑运算符,来表达复杂的条件关系。举个例子,比如我们想要筛选Sepal.Length大于7且Sepal.Width大于3的条目,可以这样操作:
-%>% filter_dt(Sepal.Length > 7 & Sepal.Width > 3) iris
+%>% filter_dt(Sepal.Length > 7 & Sepal.Width > 3) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1572,7 +1582,7 @@ 5.3.2.1.3 排序
在数据框的操作中,可以根据一个或多个变量对行进行排序。tidyfst包中,可以利用arrange_dt
函数对排序进行实现。比如,如果我们想要根据Sepal.Length进行排序,可以这样操作:
-%>% arrange_dt(Sepal.Length) iris
+%>% arrange_dt(Sepal.Length) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1585,7 +1595,7 @@
从结果中我们可以获知,默认的排序是升序排列。如果需要降序排列,那么需要在变量前面加上负号:
-%>% arrange_dt(-Sepal.Length) iris
+%>% arrange_dt(-Sepal.Length) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1598,8 +1608,8 @@
同时,可以加入多个变量,从而在第一个变量相同的情况下,根据第二个变量进行排列:
-%>% arrange_dt(Sepal.Length,Sepal.Width) %>%
- iris head() # 只观察结果的前6行
+%>% arrange_dt(Sepal.Length,Sepal.Width) %>%
+ iris head() # 只观察结果的前6行
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1617,8 +1627,8 @@ 5.3.2.1.4 更新
本节提到的更新,具体是指对某一列进行数据的更新,或者通过计算获得一个新的数据列。在tidyfst包中,可以使用mutate_dt
函数来对列进行更新。举例来说,比如我们想要让iris数据框中的Sepal.Length列全部加1,可以这样操作:
-%>%
- iris mutate_dt(Sepal.Length = Sepal.Length + 1)
+%>%
+ iris mutate_dt(Sepal.Length = Sepal.Length + 1)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1631,7 +1641,7 @@
我们也可以新增一列,比如我们想要新增一个名称为one的列,这一列的数据为常数1。
-%>% mutate_dt(one = 1) iris
+%>% mutate_dt(one = 1) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species one
<num> <num> <num> <num> <fctr> <num>
@@ -1644,9 +1654,9 @@
如果我们在更新之后,只想保留更新的那些列,可以使用transmute_dt
函数。
-%>%
- iris transmute_dt(one = 1,
- Sepal.Length = Sepal.Length + 1)
+%>%
+ iris transmute_dt(one = 1,
+ Sepal.Length = Sepal.Length + 1)
one Sepal.Length
<num> <num>
@@ -1659,7 +1669,7 @@
上面的例子中,我们就仅保留了更新后的两列。 如果需要分组更新,可以使用by参数定义分组信息。比如,我们想要把iris数据框中,根据物种进行分组,然后把Sepal.Length的平均值求出来,附在名为“sp_avg_sl”列中。操作方法如下:
-%>% mutate_dt(sp_avg_sl = mean(Sepal.Length),by = Species) iris
+%>% mutate_dt(sp_avg_sl = mean(Sepal.Length),by = Species) iris
Sepal.Length Sepal.Width Petal.Length Petal.Width Species sp_avg_sl
<num> <num> <num> <num> <fctr> <num>
@@ -1675,7 +1685,7 @@ 5.3.2.1.5 汇总
汇总,即对一系列数据进行概括的数据操作。求和、求均值、最大值、最小值,均可以视为汇总操作。比如,我们想求iris数据框中Sepal.Length的均值,可以使用tidyfst包的summarise_dt
函数。
-%>% summarise_dt(avg = mean(Sepal.Length)) iris
+%>% summarise_dt(avg = mean(Sepal.Length)) iris
avg
<num>
@@ -1684,7 +1694,7 @@
在上面的操作中,我们把最终输出的列名称设定为“avg”。在实际应用中,我们往往需要进行分组汇总操作,这可以通过设定by参数进行实现。比如我们想知道每个物种Sepal.Length的均值,可以这样操作:
-%>% summarise_dt(avg = mean(Sepal.Length),by = Species) iris
+%>% summarise_dt(avg = mean(Sepal.Length),by = Species) iris
Species avg
<fctr> <num>
@@ -1702,11 +1712,11 @@ 5.3.2.2.1 更新型连接
更新型连接(Mutating joins)是根据两个表格中的共有列进行匹配,然后完成合并的过程,可以分为内连接、外连接、左连接和右连接四种。下面,我们将会构造一个数据集来对四种连接进行说明。
-library(pacman)
-p_load(tidyfst)
-
-= data.frame(CustomerId = c(1:6), Product = c(rep("洗衣机", 3), rep("微波炉", 3)))
- df1 df1
+library(pacman)
+p_load(tidyfst)
+
+= data.frame(CustomerId = c(1:6), Product = c(rep("洗衣机", 3), rep("微波炉", 3)))
+ df1 df1
CustomerId Product
1 1 洗衣机
@@ -1716,8 +1726,8 @@
-= data.frame(CustomerId = c(2, 4, 6), Province = c(rep("广东", 2), rep("北京", 1)))
- df2 df2
+= data.frame(CustomerId = c(2, 4, 6), Province = c(rep("广东", 2), rep("北京", 1)))
+ df2 df2
CustomerId Province
1 2 广东
@@ -1727,7 +1737,7 @@
在上面的代码中,我们构造了两个数据框(df1和df2)。其中,df1中有消费者的ID号和他们买了什么产品;df2中则包含了消费者ID号和他们所在的地点(省份)。 内连接又称为自然连接,是根据两个表格某一列或多列共有的部分,进行连接的过程。下面,我们来对之前构造的两个表格进行内连接,这可以使用inner_join_dt
函数完成。
-%>% inner_join_dt(df2) df1
+%>% inner_join_dt(df2) df1
Joining by: CustomerId
@@ -1742,7 +1752,7 @@
通过上面的结果,我们可以看到,如果没有设定连接的列,那么inner_join_dt
会自动识别两个数据框中的同名列进行匹配。在内连接中,会找到df1和df2同名列CustomerId中完全匹配的条目,进行连接。如果希望直接设定合并的列,可以使用by参数来特殊指定。
-%>% inner_join_dt(df2,by = "CustomerId") df1
+%>% inner_join_dt(df2,by = "CustomerId") df1
Key: <CustomerId>
CustomerId Product Province
@@ -1754,7 +1764,7 @@
在进行内连接的时候,我们可以看到,如果不匹配的条目,会全部消失。如果想要保留这些条目,可以使用全连接,它会保留两个表格中所有的条目。而没有数值的地方,会自动填充缺失值。
-%>% full_join_dt(df2) df1
+%>% full_join_dt(df2) df1
Joining by: CustomerId
@@ -1772,7 +1782,7 @@
在上面的结果中,我们可以看到,在df2中没有消费者1、3、5的地区数据,因此填充了缺失值NA。 左连接和右连接是互为逆运算的两个操作,左连接会保留左边数据框的所有信息,但是对于右边的数据框,则只有匹配的数据得以保留,不匹配的部分会填入缺失值。下面我们来进行演示:
-%>% left_join_dt(df2) df1
+%>% left_join_dt(df2) df1
Joining by: CustomerId
@@ -1787,7 +1797,7 @@
-%>% right_join_dt(df2) df1
+%>% right_join_dt(df2) df1
Joining by: CustomerId
@@ -1802,23 +1812,23 @@
有的时候,我们需要根据两个或以上的列进行连接,那么将需要通过设置by参数来完成。下面我们举个例子:
-= fread("
- workers name company
- Nick Acme
- John Ajax
- Daniela Ajax
-")
-
-= fread("
- positions name position
- John designer
- Daniela engineer
- Cathie manager
-")
-
-= setNames(positions, c("worker", "position"))
- positions2
- workers
+= fread("
+ workers name company
+ Nick Acme
+ John Ajax
+ Daniela Ajax
+")
+
+= fread("
+ positions name position
+ John designer
+ Daniela engineer
+ Cathie manager
+")
+
+= setNames(positions, c("worker", "position"))
+ positions2
+ workers
name company
<char> <char>
@@ -1826,7 +1836,7 @@
- positions2
+ positions2
worker position
<char> <char>
@@ -1837,7 +1847,7 @@
在上面的代码中,我们获得了workers和position2两个数据框。其中,workers数据框中的name为工人名称,而position2数据框中的worker列为数据名称,因此两者合并的时候需要根据名称不同的列进行匹配:
-%>% inner_join_dt(positions2, by = c("name" = "worker")) workers
+%>% inner_join_dt(positions2, by = c("name" = "worker")) workers
Key: <name>
name company position
@@ -1852,7 +1862,7 @@ 5.3.2.2.2 过滤型连接
过滤型连接(Filtering joins)是根据两个表格中是否有匹配内容来决定一个表格中的观测是否得以保留的操作,在tidyfst包中可以使用anti_join_dt
和semi_join_dt
实现。其中,anti_join_dt
会保留第一个表格有而第二个表格中没有匹配的内容,而semi_join_dt
则会保留第一个表格有且第二个表格也有的内容。但是,第二个表格中非匹配列的其他数据不会并入生成表格中。
-%>% anti_join_dt(positions) workers
+%>% anti_join_dt(positions) workers
Joining by: name
@@ -1861,7 +1871,7 @@
-%>% semi_join_dt(positions) workers
+%>% semi_join_dt(positions) workers
Joining by: name
@@ -1877,36 +1887,36 @@ 5.3.2.2.3 集合运算操作
在R中,每个向量都可以视为一个集合,基本包提供了intersect/union/setdiff来求集合的交集、并集和补集,并可以使用setequal
函数来查看两个向量是否全等。我们可以做一个简单的演示:
-= 1:4
- x = 3:6
- y
-union(x, y) #并集
+= 1:4
+ x = 3:6
+ y
+union(x, y) #并集
[1] 1 2 3 4 5 6
-intersect(x, y) #交集
+intersect(x, y) #交集
[1] 3 4
-setdiff(x, y) #补集,x有而y没有部分
+setdiff(x, y) #补集,x有而y没有部分
[1] 1 2
-setdiff(y, x) #补集,y有而x没有部分
+setdiff(y, x) #补集,y有而x没有部分
[1] 5 6
-setequal(x, y) # x与y是否相等
+setequal(x, y) # x与y是否相等
[1] FALSE
而在tidyfst中,利用了data.table的集合运算函数,可以直接对数据框进行对应的集合运算操作。需要注意的是,所求数据框需要有相同的列名称。下面我们利用iris的前3列来做一个简单的演示:
-= iris[1:2,]
- x = iris[2:3,]
- y
-union_dt(x, y) #并集
+= iris[1:2,]
+ x = iris[2:3,]
+ y
+union_dt(x, y) #并集
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1914,32 +1924,32 @@
-intersect_dt(x, y) #交集
+intersect_dt(x, y) #交集
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
1: 4.9 3 1.4 0.2 setosa
-setdiff_dt(x, y) #补集,x有而y没有部分
+setdiff_dt(x, y) #补集,x有而y没有部分
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
1: 5.1 3.5 1.4 0.2 setosa
-setdiff_dt(y, x) #补集,y有而x没有部分
+setdiff_dt(y, x) #补集,y有而x没有部分
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
1: 4.7 3.2 1.3 0.2 setosa
-setequal_dt(x, y) # x与y是否相等
+setequal_dt(x, y) # x与y是否相等
[1] FALSE
这些函数都有all参数,可以调节其对重复值的处理。比如,如果我们取并集的时候,不需要去重,那么可以设置“all = TRUE”。
-union_dt(x,y,all = TRUE)
+union_dt(x,y,all = TRUE)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<num> <num> <num> <num> <fctr>
@@ -1966,15 +1976,15 @@
delete_na_rows
:行删除操作,如果数据框中任意行的缺失值比例或数量超过一个阈值,将整个列删除掉。
下面,我们将举个例子对上述操作进行演示。首先我们要构建一个缺失值数据框。
-library(pacman)
-p_load(tidyfst)
-
-<- data.frame(col1 = c(1:3, NA),
- df col2 = c("this", NA,NA, "text"),
- col3 = c(TRUE, FALSE, TRUE, TRUE),
- col4 = c(NA, NA, 3.2, NA))
-
- df
+library(pacman)
+p_load(tidyfst)
+
+<- data.frame(col1 = c(1:3, NA),
+ df col2 = c("this", NA,NA, "text"),
+ col3 = c(TRUE, FALSE, TRUE, TRUE),
+ col4 = c(NA, NA, 3.2, NA))
+
+ df
col1 col2 col3 col4
1 1 this TRUE NA
@@ -1985,7 +1995,7 @@
所构造的数据框中,第一、二、三、四列分别有1、2、0和3个缺失值。我们如果想要删除col2中包含缺失值的条目,可以使用drop_na_dt
函数。
-%>% drop_na_dt(col2) df
+%>% drop_na_dt(col2) df
col1 col2 col3 col4
<int> <char> <lgcl> <num>
@@ -1995,8 +2005,8 @@
如果想要删除缺失值大于等于2个或缺失比例大于等于50%的列,则可以这样操作:
-# 删除缺失值大于等于2个的列
-%>% delete_na_cols(n = 2) df
+# 删除缺失值大于等于2个的列
+%>% delete_na_cols(n = 2) df
col1 col3
<int> <lgcl>
@@ -2005,8 +2015,8 @@
-# 删除缺失比例大于等于50%的列
-%>% delete_na_cols(prop = 0.5) df
+# 删除缺失比例大于等于50%的列
+%>% delete_na_cols(prop = 0.5) df
col1 col3
<int> <lgcl>
@@ -2018,16 +2028,16 @@
如果想要删除缺失值大于等于2个或缺失比例大于等于50%的行,则可以这样操作:
-# 删除缺失值大于等于2个的行
-%>% delete_na_rows(n = 2) df
+# 删除缺失值大于等于2个的行
+%>% delete_na_rows(n = 2) df
col1 col2 col3 col4
<int> <char> <lgcl> <num>
1: 1 this TRUE NA
2: 3 <NA> TRUE 3.2
-# 删除缺失比例大于等于50%的行
-%>% delete_na_rows(prop = 0.5) df
+# 删除缺失比例大于等于50%的行
+%>% delete_na_rows(prop = 0.5) df
col1 col2 col3 col4
<int> <char> <lgcl> <num>
@@ -2041,8 +2051,8 @@ 5.3.3.1.2 缺失值替换
缺失值替换就是把缺失的部分用指定数据进行替代的过程,在tidyfst中可以使用replace_na_dt
进行实现。比如,我们要将上面所构造数据框的col1列缺失值替换为-99,可以这样操作:
-%>%
- df replace_na_dt(col1,to = -99)
+%>%
+ df replace_na_dt(col1,to = -99)
col1 col2 col3 col4
<int> <char> <lgcl> <num>
@@ -2054,8 +2064,8 @@
也可以同时对col1和col4同时进行这项操作:
-%>%
- df replace_na_dt(col1,col4,to = -99)
+%>%
+ df replace_na_dt(col1,col4,to = -99)
col1 col2 col3 col4
<int> <char> <lgcl> <num>
@@ -2067,9 +2077,9 @@
如果不设定替换列,默认替换所有的列。但需要注意的是,每一个列的类型都不一样,因此在替换的时候需要保证替换列数据类型的一致性。
-%>%
- df mutate_vars(.func = as.character) %>% #将有所列转化为字符型
- replace_na_dt(to = "missing") #将缺失值替换为“missing”
+%>%
+ df mutate_vars(.func = as.character) %>% #将有所列转化为字符型
+ replace_na_dt(to = "missing") #将缺失值替换为“missing”
col1 col2 col3 col4
<char> <char> <char> <char>
@@ -2088,8 +2098,8 @@
impute_dt
:根据列汇总数据(平均值、中位数、众数或其他)来对缺失值进行插补
我们先对fill_na_dt
函数进行讲解,它的原理非常简单,我们直接进行演示。
-# 对col2向下进行插补
-%>% fill_na_dt(col2) df
+# 对col2向下进行插补
+%>% fill_na_dt(col2) df
col1 col2 col3 col4
<int> <char> <lgcl> <num>
@@ -2098,8 +2108,8 @@
-# 对col2向上进行插补
-%>% fill_na_dt(col2,direction = "up") df
+# 对col2向上进行插补
+%>% fill_na_dt(col2,direction = "up") df
col1 col2 col3 col4
<int> <char> <lgcl> <num>
@@ -2108,8 +2118,8 @@
-# 对数值型列进行向下插补
-%>% fill_na_dt(is.numeric) df
+# 对数值型列进行向下插补
+%>% fill_na_dt(is.numeric) df
col1 col2 col3 col4
<int> <char> <lgcl> <num>
@@ -2118,8 +2128,8 @@
-# 对所有列进行向上插补
-%>% fill_na_dt(direction = "up") df
+# 对所有列进行向上插补
+%>% fill_na_dt(direction = "up") df
col1 col2 col3 col4
<int> <char> <lgcl> <num>
@@ -2131,7 +2141,7 @@
有的时候,我们会尝试用均值来对数值型的变量进行插值,那么我们可以使用impute_dt
函数进行操作:
-%>% impute_dt(is.numeric,.func = "mean") df
+%>% impute_dt(is.numeric,.func = "mean") df
col1 col2 col3 col4
<num> <char> <lgcl> <num>
@@ -2149,13 +2159,13 @@ 5.3.3.2 长宽数据转换
表格的长宽转换是一个经典的数据操作,它可以自由地改变二维表的结构。比如我们之前熟悉的iris数据框,其实就可以转化为任意的其他结构。举个例子,我们给每一朵花都进行编号,然后直接转为长表格式。
-library(pacman)
-p_load(tidyfst)
-
-%>%
- iris mutate_vars(.func = as.character) %>% #所有数据转化为字符型
- mutate_dt(id = 1:.N) %>% # 给所有花进行编号
- longer_dt(id) # 以编号id作为分组变量,转化为长表
+library(pacman)
+p_load(tidyfst)
+
+%>%
+ iris mutate_vars(.func = as.character) %>% #所有数据转化为字符型
+ mutate_dt(id = 1:.N) %>% # 给所有花进行编号
+ longer_dt(id) # 以编号id作为分组变量,转化为长表
id name value
<int> <fctr> <char>
@@ -2171,110 +2181,110 @@ 5.3.3.2.1 宽表转长表
在tidyfst包中,可以使用longer_dt
函数来把宽表转化为长表,需要定义的核心参数是数据框和分组列。分组列就是不参与长宽变换的列,而其他列名称将会统统聚合起来成为一列。下面我们进行一个简单的演示。首先,我们先进行数据准备:
-= data.frame(
- stocks time = as.Date('2009-01-01') + 0:9,
- X = rnorm(10, 0, 1),
- Y = rnorm(10, 0, 2),
- Z = rnorm(10, 0, 4)
-
- )
- stocks
-
- time X Y Z
-1 2009-01-01 -0.41951421 -4.0696697 1.1862528
-2 2009-01-02 -1.95653982 1.2851513 -4.3121715
-3 2009-01-03 -0.18057417 0.2530406 1.4529063
-4 2009-01-04 1.53254389 2.5200584 1.2337196
-5 2009-01-05 -0.40798547 -3.1497638 -2.6830911
-6 2009-01-06 2.09614174 4.4814026 2.1697771
-7 2009-01-07 -0.39973265 -0.4680301 1.6492286
-8 2009-01-08 0.33918122 -2.1085464 1.9916131
-9 2009-01-09 0.25558423 2.7826645 0.3446163
-10 2009-01-10 -0.09429387 -0.9727120 -1.4884806
+= data.frame(
+ stocks time = as.Date('2009-01-01') + 0:9,
+ X = rnorm(10, 0, 1),
+ Y = rnorm(10, 0, 2),
+ Z = rnorm(10, 0, 4)
+
+ )
+ stocks
+
+ time X Y Z
+1 2009-01-01 0.281683357 0.76471698 -2.5342818
+2 2009-01-02 0.623717987 -2.68345066 -3.4767958
+3 2009-01-03 -1.095659662 1.55443409 -2.2950831
+4 2009-01-04 0.340494860 -0.62615790 1.6633414
+5 2009-01-05 1.637452081 1.74396217 5.2667718
+6 2009-01-06 0.005707745 -4.29363758 5.9902291
+7 2009-01-07 -0.495548864 -1.22534932 6.4509272
+8 2009-01-08 1.001418629 -0.02843278 -4.8999951
+9 2009-01-09 1.919028184 3.46398763 -4.0807348
+10 2009-01-10 0.081246615 2.18895188 0.2073267
观察数据,我们知道这是一个10行4列的数据框,一列为时间time,其余三列为数值列。现在,我们要把它转化为长表。
-%>%
- stocks longer_dt(time) -> longer_table
-
- longer_table
-
- time name value
- <Date> <fctr> <num>
- 1: 2009-01-01 X -0.41951421
- 2: 2009-01-02 X -1.95653982
- 3: 2009-01-03 X -0.18057417
- 4: 2009-01-04 X 1.53254389
- 5: 2009-01-05 X -0.40798547
- 6: 2009-01-06 X 2.09614174
- 7: 2009-01-07 X -0.39973265
- 8: 2009-01-08 X 0.33918122
- 9: 2009-01-09 X 0.25558423
-10: 2009-01-10 X -0.09429387
-11: 2009-01-01 Y -4.06966965
-12: 2009-01-02 Y 1.28515135
-13: 2009-01-03 Y 0.25304059
-14: 2009-01-04 Y 2.52005836
-15: 2009-01-05 Y -3.14976381
-16: 2009-01-06 Y 4.48140262
-17: 2009-01-07 Y -0.46803013
-18: 2009-01-08 Y -2.10854639
-19: 2009-01-09 Y 2.78266455
-20: 2009-01-10 Y -0.97271195
-21: 2009-01-01 Z 1.18625279
-22: 2009-01-02 Z -4.31217152
-23: 2009-01-03 Z 1.45290630
-24: 2009-01-04 Z 1.23371964
-25: 2009-01-05 Z -2.68309108
-26: 2009-01-06 Z 2.16977710
-27: 2009-01-07 Z 1.64922855
-28: 2009-01-08 Z 1.99161315
-29: 2009-01-09 Z 0.34461627
-30: 2009-01-10 Z -1.48848060
- time name value
+%>%
+ stocks longer_dt(time) -> longer_table
+
+ longer_table
+
+ time name value
+ <Date> <fctr> <num>
+ 1: 2009-01-01 X 0.281683357
+ 2: 2009-01-02 X 0.623717987
+ 3: 2009-01-03 X -1.095659662
+ 4: 2009-01-04 X 0.340494860
+ 5: 2009-01-05 X 1.637452081
+ 6: 2009-01-06 X 0.005707745
+ 7: 2009-01-07 X -0.495548864
+ 8: 2009-01-08 X 1.001418629
+ 9: 2009-01-09 X 1.919028184
+10: 2009-01-10 X 0.081246615
+11: 2009-01-01 Y 0.764716980
+12: 2009-01-02 Y -2.683450664
+13: 2009-01-03 Y 1.554434086
+14: 2009-01-04 Y -0.626157901
+15: 2009-01-05 Y 1.743962172
+16: 2009-01-06 Y -4.293637579
+17: 2009-01-07 Y -1.225349317
+18: 2009-01-08 Y -0.028432778
+19: 2009-01-09 Y 3.463987634
+20: 2009-01-10 Y 2.188951879
+21: 2009-01-01 Z -2.534281801
+22: 2009-01-02 Z -3.476795793
+23: 2009-01-03 Z -2.295083131
+24: 2009-01-04 Z 1.663341410
+25: 2009-01-05 Z 5.266771836
+26: 2009-01-06 Z 5.990229085
+27: 2009-01-07 Z 6.450927170
+28: 2009-01-08 Z -4.899995125
+29: 2009-01-09 Z -4.080734833
+30: 2009-01-10 Z 0.207326711
+ time name value
可以发现,列名称X/Y/Z都在name列中,其值则在value列中。这些列名称可以通过更改name和value参数重新被定义。
-%>%
- stocks longer_dt(time,
- name = "var",
- value = "val")
-
- time var val
- <Date> <fctr> <num>
- 1: 2009-01-01 X -0.41951421
- 2: 2009-01-02 X -1.95653982
- 3: 2009-01-03 X -0.18057417
- 4: 2009-01-04 X 1.53254389
- 5: 2009-01-05 X -0.40798547
- 6: 2009-01-06 X 2.09614174
- 7: 2009-01-07 X -0.39973265
- 8: 2009-01-08 X 0.33918122
- 9: 2009-01-09 X 0.25558423
-10: 2009-01-10 X -0.09429387
-11: 2009-01-01 Y -4.06966965
-12: 2009-01-02 Y 1.28515135
-13: 2009-01-03 Y 0.25304059
-14: 2009-01-04 Y 2.52005836
-15: 2009-01-05 Y -3.14976381
-16: 2009-01-06 Y 4.48140262
-17: 2009-01-07 Y -0.46803013
-18: 2009-01-08 Y -2.10854639
-19: 2009-01-09 Y 2.78266455
-20: 2009-01-10 Y -0.97271195
-21: 2009-01-01 Z 1.18625279
-22: 2009-01-02 Z -4.31217152
-23: 2009-01-03 Z 1.45290630
-24: 2009-01-04 Z 1.23371964
-25: 2009-01-05 Z -2.68309108
-26: 2009-01-06 Z 2.16977710
-27: 2009-01-07 Z 1.64922855
-28: 2009-01-08 Z 1.99161315
-29: 2009-01-09 Z 0.34461627
-30: 2009-01-10 Z -1.48848060
- time var val
+%>%
+ stocks longer_dt(time,
+ name = "var",
+ value = "val")
+
+ time var val
+ <Date> <fctr> <num>
+ 1: 2009-01-01 X 0.281683357
+ 2: 2009-01-02 X 0.623717987
+ 3: 2009-01-03 X -1.095659662
+ 4: 2009-01-04 X 0.340494860
+ 5: 2009-01-05 X 1.637452081
+ 6: 2009-01-06 X 0.005707745
+ 7: 2009-01-07 X -0.495548864
+ 8: 2009-01-08 X 1.001418629
+ 9: 2009-01-09 X 1.919028184
+10: 2009-01-10 X 0.081246615
+11: 2009-01-01 Y 0.764716980
+12: 2009-01-02 Y -2.683450664
+13: 2009-01-03 Y 1.554434086
+14: 2009-01-04 Y -0.626157901
+15: 2009-01-05 Y 1.743962172
+16: 2009-01-06 Y -4.293637579
+17: 2009-01-07 Y -1.225349317
+18: 2009-01-08 Y -0.028432778
+19: 2009-01-09 Y 3.463987634
+20: 2009-01-10 Y 2.188951879
+21: 2009-01-01 Z -2.534281801
+22: 2009-01-02 Z -3.476795793
+23: 2009-01-03 Z -2.295083131
+24: 2009-01-04 Z 1.663341410
+25: 2009-01-05 Z 5.266771836
+26: 2009-01-06 Z 5.990229085
+27: 2009-01-07 Z 6.450927170
+28: 2009-01-08 Z -4.899995125
+29: 2009-01-09 Z -4.080734833
+30: 2009-01-10 Z 0.207326711
+ time var val
@@ -2282,58 +2292,58 @@ 5.3.3.2.2 长表转宽表
长表转为宽表是宽表转长表的逆运算,因此需要定义的核心参数也有相仿之处,需要知道数据框、分组列的信息,同时需要知道名称列(name)和数值列(value)分别来自哪里。以上面生成的longer_table为例,我们尝试把它进行还原。
- longer_table
-
- time name value
- <Date> <fctr> <num>
- 1: 2009-01-01 X -0.41951421
- 2: 2009-01-02 X -1.95653982
- 3: 2009-01-03 X -0.18057417
- 4: 2009-01-04 X 1.53254389
- 5: 2009-01-05 X -0.40798547
- 6: 2009-01-06 X 2.09614174
- 7: 2009-01-07 X -0.39973265
- 8: 2009-01-08 X 0.33918122
- 9: 2009-01-09 X 0.25558423
-10: 2009-01-10 X -0.09429387
-11: 2009-01-01 Y -4.06966965
-12: 2009-01-02 Y 1.28515135
-13: 2009-01-03 Y 0.25304059
-14: 2009-01-04 Y 2.52005836
-15: 2009-01-05 Y -3.14976381
-16: 2009-01-06 Y 4.48140262
-17: 2009-01-07 Y -0.46803013
-18: 2009-01-08 Y -2.10854639
-19: 2009-01-09 Y 2.78266455
-20: 2009-01-10 Y -0.97271195
-21: 2009-01-01 Z 1.18625279
-22: 2009-01-02 Z -4.31217152
-23: 2009-01-03 Z 1.45290630
-24: 2009-01-04 Z 1.23371964
-25: 2009-01-05 Z -2.68309108
-26: 2009-01-06 Z 2.16977710
-27: 2009-01-07 Z 1.64922855
-28: 2009-01-08 Z 1.99161315
-29: 2009-01-09 Z 0.34461627
-30: 2009-01-10 Z -1.48848060
- time name value
-
-%>%
- longer_table wider_dt(time,name = "name",value = "value")
+ longer_table
+
+ time name value
+ <Date> <fctr> <num>
+ 1: 2009-01-01 X 0.281683357
+ 2: 2009-01-02 X 0.623717987
+ 3: 2009-01-03 X -1.095659662
+ 4: 2009-01-04 X 0.340494860
+ 5: 2009-01-05 X 1.637452081
+ 6: 2009-01-06 X 0.005707745
+ 7: 2009-01-07 X -0.495548864
+ 8: 2009-01-08 X 1.001418629
+ 9: 2009-01-09 X 1.919028184
+10: 2009-01-10 X 0.081246615
+11: 2009-01-01 Y 0.764716980
+12: 2009-01-02 Y -2.683450664
+13: 2009-01-03 Y 1.554434086
+14: 2009-01-04 Y -0.626157901
+15: 2009-01-05 Y 1.743962172
+16: 2009-01-06 Y -4.293637579
+17: 2009-01-07 Y -1.225349317
+18: 2009-01-08 Y -0.028432778
+19: 2009-01-09 Y 3.463987634
+20: 2009-01-10 Y 2.188951879
+21: 2009-01-01 Z -2.534281801
+22: 2009-01-02 Z -3.476795793
+23: 2009-01-03 Z -2.295083131
+24: 2009-01-04 Z 1.663341410
+25: 2009-01-05 Z 5.266771836
+26: 2009-01-06 Z 5.990229085
+27: 2009-01-07 Z 6.450927170
+28: 2009-01-08 Z -4.899995125
+29: 2009-01-09 Z -4.080734833
+30: 2009-01-10 Z 0.207326711
+ time name value
+
+%>%
+ longer_table wider_dt(time,name = "name",value = "value")
Key: <time>
- time X Y Z
- <Date> <num> <num> <num>
- 1: 2009-01-01 -0.41951421 -4.0696697 1.1862528
- 2: 2009-01-02 -1.95653982 1.2851513 -4.3121715
- 3: 2009-01-03 -0.18057417 0.2530406 1.4529063
- 4: 2009-01-04 1.53254389 2.5200584 1.2337196
- 5: 2009-01-05 -0.40798547 -3.1497638 -2.6830911
- 6: 2009-01-06 2.09614174 4.4814026 2.1697771
- 7: 2009-01-07 -0.39973265 -0.4680301 1.6492286
- 8: 2009-01-08 0.33918122 -2.1085464 1.9916131
- 9: 2009-01-09 0.25558423 2.7826645 0.3446163
-10: 2009-01-10 -0.09429387 -0.9727120 -1.4884806
+ time X Y Z
+ <Date> <num> <num> <num>
+ 1: 2009-01-01 0.281683357 0.76471698 -2.5342818
+ 2: 2009-01-02 0.623717987 -2.68345066 -3.4767958
+ 3: 2009-01-03 -1.095659662 1.55443409 -2.2950831
+ 4: 2009-01-04 0.340494860 -0.62615790 1.6633414
+ 5: 2009-01-05 1.637452081 1.74396217 5.2667718
+ 6: 2009-01-06 0.005707745 -4.29363758 5.9902291
+ 7: 2009-01-07 -0.495548864 -1.22534932 6.4509272
+ 8: 2009-01-08 1.001418629 -0.02843278 -4.8999951
+ 9: 2009-01-09 1.919028184 3.46398763 -4.0807348
+10: 2009-01-10 0.081246615 2.18895188 0.2073267
在上面的操作中,我们把time定义为分组列,然后以字符形式来定义哪一列是名称列,哪一列是数值列。在宽表转长表的时候,name和value如果不自定义,就会自动给名称列命名为“name”,给数值列命名为“value”;但是在长表转为宽表的时候,则必须手动进行定义,否则计算机无法自动识别。