如何同时旋转多列?
How to pivot multiple columns at the same time?
我有一个数据框,其中包含如下 input
中组织的试题。
我正在尝试以 output
.
中显示的整洁方式组织它
在 input
中,您可以看到学生的 ID
、他们对特定项目的回答 suffix = ".text"
、他们对该特定项目的分数 suffix = ".score"
,以及他们的 total
得分。
输入
library(tibble)
input <- tribble(
~ID, ~i1.text, ~i1.score, ~i2.text, ~i2.score, ~total,
"Mark", "A", 0L, "B", 1L, 1L,
"Mary", "C", 1L, "D", 0L, 1L,
"John", "A", 0L, "B", 1L, 1L,
"Abby", "C", 1L, "B", 1L, 2L
)
我需要将数据转换为如下所示。
我很确定我可以用 pivot_longer()
做到这一点,但我很迷茫。
预期输出
output <- tribble(
~ID, ~item, ~text, ~score, ~total,
"Mark", "i1", "A", 0L, 1L,
"Mark", "i2", "B", 1L, 1L,
"Mary", "i1", "C", 1L, 1L,
"Mary", "i2", "D", 0L, 1L,
"John", "i1", "A", 0L, 1L,
"John", "i2", "B", 1L, 1L,
"Abby", "i1", "C", 1L, 2L,
"Abby", "i2", "B", 2L, 2L
)
output
# A tibble: 8 × 5
ID item text score total
<chr> <chr> <chr> <int> <int>
1 Mark i1 A 0 1
2 Mark i2 B 1 1
3 Mary i1 C 1 1
4 Mary i2 D 0 1
5 John i1 A 0 1
6 John i2 B 1 1
7 Abby i1 C 1 2
8 Abby i2 B 2 2
我们可以使用 pivot_longer
和 names_sep
作为 .
- 'item' return [=14] 之前的列名称的前缀部分=] 和 .value
将 return 带有列名称后缀部分的列的值 .
library(tidyr)
pivot_longer(input, cols = contains("."),
names_to = c("item", ".value"), names_sep = "\.")
-输出
# A tibble: 8 × 5
ID total item text score
<chr> <int> <chr> <chr> <int>
1 Mark 1 i1 A 0
2 Mark 1 i2 B 1
3 Mary 1 i1 C 1
4 Mary 1 i2 D 0
5 John 1 i1 A 0
6 John 1 i2 B 1
7 Abby 2 i1 C 1
8 Abby 2 i2 B 1
这是一个类似的替代方法,使用 names_pattern
:
解释:(.*)\.(.*)
是正则表达式:
()
抓一组
.
捕获任何字符
*
是量词表示0个或多个
\
转义字符
正则表达式的意思是:
任意数量的字符后跟一个点,然后是任意数量的字符。此正则表达式匹配您的列名:
library(dplyr)
library(tidyr)
input %>%
pivot_longer(
cols = -c(ID, total),
names_to = c('item', '.value'),
names_pattern = '(.*)\.(.*)'
)
ID total item text score
<chr> <int> <chr> <chr> <int>
1 Mark 1 i1 A 0
2 Mark 1 i2 B 1
3 Mary 1 i1 C 1
4 Mary 1 i2 D 0
5 John 1 i1 A 0
6 John 1 i2 B 1
7 Abby 2 i1 C 1
8 Abby 2 i2 B 1
我有一个数据框,其中包含如下 input
中组织的试题。
我正在尝试以 output
.
在 input
中,您可以看到学生的 ID
、他们对特定项目的回答 suffix = ".text"
、他们对该特定项目的分数 suffix = ".score"
,以及他们的 total
得分。
输入
library(tibble)
input <- tribble(
~ID, ~i1.text, ~i1.score, ~i2.text, ~i2.score, ~total,
"Mark", "A", 0L, "B", 1L, 1L,
"Mary", "C", 1L, "D", 0L, 1L,
"John", "A", 0L, "B", 1L, 1L,
"Abby", "C", 1L, "B", 1L, 2L
)
我需要将数据转换为如下所示。
我很确定我可以用 pivot_longer()
做到这一点,但我很迷茫。
预期输出
output <- tribble(
~ID, ~item, ~text, ~score, ~total,
"Mark", "i1", "A", 0L, 1L,
"Mark", "i2", "B", 1L, 1L,
"Mary", "i1", "C", 1L, 1L,
"Mary", "i2", "D", 0L, 1L,
"John", "i1", "A", 0L, 1L,
"John", "i2", "B", 1L, 1L,
"Abby", "i1", "C", 1L, 2L,
"Abby", "i2", "B", 2L, 2L
)
output
# A tibble: 8 × 5
ID item text score total
<chr> <chr> <chr> <int> <int>
1 Mark i1 A 0 1
2 Mark i2 B 1 1
3 Mary i1 C 1 1
4 Mary i2 D 0 1
5 John i1 A 0 1
6 John i2 B 1 1
7 Abby i1 C 1 2
8 Abby i2 B 2 2
我们可以使用 pivot_longer
和 names_sep
作为 .
- 'item' return [=14] 之前的列名称的前缀部分=] 和 .value
将 return 带有列名称后缀部分的列的值 .
library(tidyr)
pivot_longer(input, cols = contains("."),
names_to = c("item", ".value"), names_sep = "\.")
-输出
# A tibble: 8 × 5
ID total item text score
<chr> <int> <chr> <chr> <int>
1 Mark 1 i1 A 0
2 Mark 1 i2 B 1
3 Mary 1 i1 C 1
4 Mary 1 i2 D 0
5 John 1 i1 A 0
6 John 1 i2 B 1
7 Abby 2 i1 C 1
8 Abby 2 i2 B 1
这是一个类似的替代方法,使用 names_pattern
:
解释:(.*)\.(.*)
是正则表达式:
()
抓一组
.
捕获任何字符
*
是量词表示0个或多个
\
转义字符
正则表达式的意思是: 任意数量的字符后跟一个点,然后是任意数量的字符。此正则表达式匹配您的列名:
library(dplyr)
library(tidyr)
input %>%
pivot_longer(
cols = -c(ID, total),
names_to = c('item', '.value'),
names_pattern = '(.*)\.(.*)'
)
ID total item text score
<chr> <int> <chr> <chr> <int>
1 Mark 1 i1 A 0
2 Mark 1 i2 B 1
3 Mary 1 i1 C 1
4 Mary 1 i2 D 0
5 John 1 i1 A 0
6 John 1 i2 B 1
7 Abby 2 i1 C 1
8 Abby 2 i2 B 1