tidyr之gather、separate、spread…

本文介绍了使用 R 语言包 tidyr 进行数据整理的方法,包括 gather 用于长宽表转换,separate 用于拆分列,separate_rows 用于拆分单元格,spread 用于展平数据,unite 用于合并列。

使用tidyr的时候也有可能需要dplyr包。

gather的用法:

   gather(data, key, value, ..., na.rm = FALSE, convert = FALSE,
factor_key = FALSE)

data为要处理的数据,key为新创建的变量,value为创建变量下的数值。...为列的设定,比如下面的例子创建变量stock,而不需要把time变成变量下的数值,则用X:Z或-time。

stocks <- data.frame(
     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 -1.06024371 -1.3799111  1.2076349
2  2009-01-02 -0.49010731 -2.4870899  3.7888550
3  2009-01-03  1.15709245 -1.5708653  2.2164464
4  2009-01-04 -0.52049101  1.9813593  2.0094476
5  2009-01-05  0.60130291 -2.6300865 -3.9681798
6  2009-01-06 -0.09306031 -0.8420800  0.6704426
7  2009-01-07 -0.83323255 -1.4147638  2.3398504
8  2009-01-08 -0.15517432  1.8773903  1.6437630
9  2009-01-09  0.36519166  0.3696238  1.5746588
10 2009-01-10  0.09442596 -0.5840472 -1.0298875
 stocks %>% gather(stock, price, -time)
         time stock       price
1  2009-01-01     X -1.06024371
2  2009-01-02     X -0.49010731
3  2009-01-03     X  1.15709245
4  2009-01-04     X -0.52049101
5  2009-01-05     X  0.60130291
6  2009-01-06     X -0.09306031
7  2009-01-07     X -0.83323255
8  2009-01-08     X -0.15517432
9  2009-01-09     X  0.36519166
10 2009-01-10     X  0.09442596
11 2009-01-01     Y -1.37991110
12 2009-01-02     Y -2.48708993
13 2009-01-03     Y -1.57086533
14 2009-01-04     Y  1.98135935
15 2009-01-05     Y -2.63008648
16 2009-01-06     Y -0.84208003
17 2009-01-07     Y -1.41476385
18 2009-01-08     Y  1.87739029
19 2009-01-09     Y  0.36962382
20 2009-01-10     Y -0.58404720
21 2009-01-01     Z  1.20763492
22 2009-01-02     Z  3.78885500
23 2009-01-03     Z  2.21644638
24 2009-01-04     Z  2.00944760
25 2009-01-05     Z -3.96817978
26 2009-01-06     Z  0.67044262
27 2009-01-07     Z  2.33985039
28 2009-01-08     Z  1.64376300
29 2009-01-09     Z  1.57465875
30 2009-01-10     Z -1.02988745

gather_的用法如上,只是更适合于编程用。

 

separate的用法:

separate(data, col, into, sep = "[^[:alnum:]]+", remove =TRUE,
convert = FALSE, extra = "warn", fill = "warn", ...)

data为要处理的数据;col为要选择的变量名;into为要分割为几个变量的名;sep为正则表达式,用于分割;extra为在字符串过多的情况下处理;fill为在字符串过少的情况下处理。

> df <- data.frame(x = c(NA, "a.b", "a.d","b.c"))
> df %>% separate(x, c("A", "B"))
     A    B
1  
2    a    b
3    a    d
4    b    c
> df <- data.frame(x = c("a", "a b", "a b c", NA))
> df
      x
1     a
2   a b
3 a b c
4  
df %>% separate(x, c("a", "b"), extra = "merge", fill = "left")
     a    b
1     a
2    a    b
3    a  b c
4  
> df <- data.frame(x = c("x: 123", "y: error: 7"))
> df
            x
1      x: 123
2 y: error: 7
> df %>% separate(x, c("key", "value"), sep = ":", extra = "merge")
  key     value
1   x       123
2   y  error: 7

separate_的用法如上,但更适用于编程。

separate_rows的用法:

separate_rows(data, ..., sep = "[^[:alnum:].]+", convert =FALSE)

> df <- data.frame(
+     x = 1:3,
+     y = c("a","d,e,f","g,h"),
+     z = c("1","2,3,4","5,6"),
+     stringAsFactors =F
+ )
> separate_rows(df, y, z, convert = T)
  x stringAsFactors y z
1 1           FALSE a 1
2 2           FALSE d 2
3 2           FALSE e 3
4 2           FALSE f 4
5 3           FALSE g 5
6 3           FALSE h 6

而使用separate_rows(df, c("y","z"), convert =T)是不对的,必须使用separate_rows_ 才可。

spread的用法:

spread(data, key, value, fill = NA, convert = FALSE, drop =TRUE,
sep = NULL)

data为要扩展的数据,key为列的名字,其值将用于列表的表头, value将填充列表的值;fill为填充数据的缺失值。

使用上面的stocks例子

> stocksm <- stocks %>% gather(stock, price, -time)
> stocksm %>% spread(stock, price)
         time           X           Y          Z
1  2009-01-01 -1.04456577 -0.97179381  2.4330105
2  2009-01-02 -0.09717072 -0.77313257 -2.3443736
3  2009-01-03  1.36933739  1.54137383  0.6551325
4  2009-01-04  2.13655070 -0.05889974  1.9988306
5  2009-01-05  0.39546822  3.80644394  3.7166546
6  2009-01-06  0.09720381 -0.44658971  0.5136471
7  2009-01-07 -0.50775134 -2.53712365  0.2004835
8  2009-01-08 -1.65134456  1.01235639 10.4377141
9  2009-01-09 -1.62622446 -0.80074087  3.0444515
10 2009-01-10 -0.37272122  3.86510320  4.7424977
> stocksm %>% spread(time, price)
  stock 2009-01-01  2009-01-02 2009-01-03  2009-01-04 2009-01-05
1     X -1.0445658 -0.09717072  1.3693374  2.13655070  0.3954682
2     Y -0.9717938 -0.77313257  1.5413738 -0.05889974  3.8064439
3     Z  2.4330105 -2.34437356  0.6551325  1.99883061  3.7166546
   2009-01-06 2009-01-07 2009-01-08 2009-01-09 2009-01-10
1  0.09720381 -0.5077513  -1.651345 -1.6262245 -0.3727212
2 -0.44658971 -2.5371237   1.012356 -0.8007409  3.8651032
3  0.51364707  0.2004835  10.437714  3.0444515  4.7424977

spread_用于编程。

unite的用法:

unite(data, col, ..., sep = "_", remove = TRUE)

data为数据;col为创建的变量;...为要合并的列名;sep为要为合并的变量添加的符号。

> mtcars %>%
     unite(vs_am, vs, am)
                     mpg cyl  disp  hp drat    wt  qsec vs_am gear
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46   0_1    4
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02   0_1    4
Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61   1_1    4
Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44   1_0    3
Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02   0_0    3
Valiant             18.1   6 225.0 105 2.76 3.460 20.22   1_0    3

也可用unite_:

> mtcars %>%
     unite_("vs_am", c("vs","am"))
                     mpg cyl  disp  hp drat    wt  qsec vs_am gear
Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46   0_1    4
Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02   0_1    4
Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61   1_1    4
Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44   1_0    3
Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02   0_0    3
Valiant             18.1   6 225.0 105 2.76 3.460 20.22   1_0    3

 

 

<think>好的,我现在需要帮助用户学习如何使用R语言的tidyr包进行数据变形,特别是提供教程和示例。首先,我得回忆一下tidyr包的主要功能和常用函数。记得tidyr主要用于数据清洗和整理,将数据转换为Tidy Data格式,也就是每个变量一列,每个观测一行,每个表格一种观测类型的数据。 根据用户提供的引用内容,比如引用[2]和[3],spread函数和gather函数是关键。用户可能需要将长格式转换为宽格式,或者相反。比如,spread函数可以将键值对展开成列,而gather则是将多列合并成键值对。另外,引用[4]提到dplyr和tidyr一起使用,可能需要在回答中结合这两个包的操作,比如使用管道操作符%>%。 接下来,我需要整理出具体的步骤和示例。首先安装和加载tidyr包,然后准备示例数据。例如,创建一个包含年份、季度和销售额的长格式数据框。然后展示如何使用spread函数将季度作为列,销售额填充到对应的位置。同样地,再展示gather函数将宽格式转换回长格式。 另外,可能需要提到其他函数,比如separate和unite,用于分割和合并列。例如,日期列分割成年、月、日,或者合并多个列成一个。这些操作也是数据变形中常见的需求。 用户还可能需要了解如何处理缺失值,比如drop_na函数,或者填充缺失值fill函数。这部分在数据清洗中也很重要,但用户的问题主要集中在变形,可能需要简要提及。 然后,根据用户提供的引用,特别是引用[2]中的示例,需要确保代码正确,并且用R语言展示。同时,要符合用户的要求,使用中文回答,结构清晰,分步骤说明。 最后,生成相关问题,可能涉及tidyr的其他函数,与dplyr的结合使用,或者实际应用中的案例。例如,处理多层索引或复杂数据结构的问题,或者在数据可视化前的整理步骤。 需要检查是否符合所有系统级指令,比如数学公式的格式是否正确,独立公式使用$$...$$,但在这个问题中可能涉及较少数学公式,更多是代码示例。确保代码块用反引号包裹,并正确标注语言类型。 总结步骤: 1. 介绍tidyr的作用和Tidy Data概念。 2. 安装和加载包。 3. 示例数据准备。 4. 使用gatherspread进行长宽转换。 5. 其他函数如separate和unite的示例。 6. 结合dplyr的管道操作。 7. 处理缺失值的函数。 8. 生成相关问题。 需要确保每个步骤都有代码示例,并解释清楚每个函数的作用。同时,引用用户提供的参考文献,比如引用[2]中的spread示例,引用[3]中的功能列表,引用[4]中的Tidy Data定义,正确标注引用标识。 可能遇到的问题:用户可能对Tidy Data概念不熟悉,需要简要解释。另外,示例数据需要简单明了,方便用户理解。此外,代码的正确性很重要,需要验证示例代码是否能够运行,比如spread的参数是否正确,是否使用最新的tidyr语法(注意tidyr的更新可能导致函数参数变化,例如spread和pivot_wider的区别,但根据引用[2],用户提到的是spread函数,可能使用的是旧版tidyr,但需要指出现在推荐使用pivot_wider和pivot_longer)。 因此,在回答中可能需要提到,从tidyr 1.0.0开始,spreadgather被pivot_wider和pivot_longer取代,但为了兼容旧版或用户当前的学习资料,仍然展示spreadgather的用法,同时建议新用户使用新的pivot函数。这可以作为一个注意事项,帮助用户避免混淆。 最后,确保回答结构清晰,分点说明,代码示例正确,引用标注正确,并且生成的相关问题能够引导用户进一步学习。</think>### 使用tidyr进行数据变形的教程及示例 tidyr是R语言中用于数据清洗和整理的核心工具包,其核心目标是将数据转换为**Tidy Data**格式:每个变量占一列,每个观测值占一行,每个表格存储一种观测类型[^4]。以下是关键操作的教学示例: --- #### 1. 安装与加载 ```r install.packages("tidyr") # 安装包 library(tidyr) # 加载包 library(dplyr) # 通常与dplyr配合使用 ``` --- #### 2. 长格式 ↔ 宽格式转换 **示例数据**: ```r sales_data <- tibble( year = c(2020, 2020, 2021, 2021), quarter = c("Q1", "Q2", "Q1", "Q2"), revenue = c(100, 150, 120, 180) ) ``` - **宽格式转长格式**:`gather()` ```r long_data <- sales_data %>% gather(key = "metric", value = "value", revenue) # key列为新变量名,value列为数值列 ``` - **长格式转宽格式**:`spread()` ```r wide_data <- sales_data %>% spread(key = quarter, value = revenue) # 将quarter列的值展开为列名[^2] ``` 结果示例: ``` year Q1 Q2 <dbl> <dbl> <dbl> 1 2020 100 150 2 2021 120 180 ``` --- #### 3. 列的分割与合并 - **分割列**:`separate()` 将复合字段拆分为多列: ```r data <- tibble(date = c("2023-01", "2023-02")) separated_data <- data %>% separate(date, into = c("year", "month"), sep = "-") ``` - **合并列**:`unite()` 将多列合并为一列: ```r united_data <- separated_data %>% unite("date", year, month, sep = "-") ``` --- #### 4. 处理缺失值 - **删除缺失值**:`drop_na()` ```r clean_data <- sales_data %>% drop_na() ``` - **填充缺失值**:`fill()` ```r filled_data <- sales_data %>% fill(revenue, .direction = "down") ``` --- #### 5. 与dplyr结合使用 通过管道操作符`%>%`实现复杂变形: ```r result <- sales_data %>% filter(year >= 2020) %>% # 筛选年份 spread(quarter, revenue) %>% # 转为宽格式 mutate(total = Q1 + Q2) # 新增总销售额列 ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值