我有一个正在使用的数据集,我正在尝试使用tidyverse进行重塑。
发件人:
|Name |eval |test |type | score|
|:----|:------|:----|:---------|-----:|
|John |first |1 |pretest | 10|
|John |first |1 |posttest | 15|
|John |first |2 |pretest | 20|
|John |first |2 |posttest | 30|
|John |second |1 |pretest | 35|
|John |second |1 |posttest | 50|
|John |second |2 |pretest | 5|
|John |second |2 |posttest | 10|
|Jane |first |1 |pretest | 40|
|Jane |first |1 |posttest | 20|
|Jane |first |2 |pretest | 10|
|Jane |first |2 |posttest | 20|
收件人:
|Name |eval |new_name | pre_test| post_test|
|:----|:------|:-------------|--------:|---------:|
|John |first |John_first_1 | 10| 15|
|John |first |John_first_2 | 20| 30|
|John |second |John_second_1 | 35| 50|
|John |second |John_second_2 | 5| 10|
|Jane |first |Jane_first_1 | 40| 20|
|Jane |first |Jane_first_2 | 10| 20|
尝试进行 group_by ,以便对name,eval和test进行group_by,以便每个组本质上是给定人员的pre_test与post_test。
还尝试在名称,评估,测试和类型上使用 unite 。但是如果之后我进行传播,那么每个唯一名称最终都会由许多列组成。
还尝试先在名称上进行 unite ,评估,然后进行测试,然后使用key =(新的统一名称)和value =进行传播值,但输出不是我想要的
我知道可以编写一个循环函数以获取其他所有值并将其放入新列中,但是我正在尝试查看是否有 tidyverse 方式可以解决此问题。
谢谢!
library(tidyverse)
Name <- c('John', 'John', 'John', 'John',
'John', 'John', 'John', 'John',
'Jane', 'Jane', 'Jane', 'Jane')
eval <- c('first', 'first', 'first', 'first',
'second', 'second', 'second', 'second',
'first', 'first', 'first', 'first')
test <- c('1', '1', '2', '2',
'1', '1', '2', '2',
'1', '1', '2', '2')
type <- c('pretest', 'posttest', 'pretest', 'posttest',
'pretest', 'posttest', 'pretest', 'posttest',
'pretest', 'posttest', 'pretest', 'posttest')
score <- c(10, 15, 20, 30, 35, 50, 5, 10, 40, 20, 10, 20)
df <- data.frame(Name, eval, test, type, score)
df %>%
unite(temp, Name, eval, test) %>%
spread(key=type, value=score)
编辑以显示 akrun 的代码所处理的原始表 发件人:
|Name |eval |test |type | score|
|:----|:------|:----|:---------|-----:|
|John |first |1 |pretest | 10|
|John |first |1 |posttest | 15|
|John |first |2 |pretest | 20|
|John |first |2 |postttest | 30|
|John |second |1 |pretest | 35|
|John |second |1 |posttest | 50|
|John |second |2 |pretest | 5|
|John |second |2 |postttest | 10|
|Jane |first |1 |pretest | 40|
|Jane |first |1 |posttest | 20|
|Jane |first |2 |pretest | 10|
|Jane |first |2 |postttest | 20|
答案 0 :(得分:2)
我们可以替换“类型”列中的多个“ t”以使其相同,然后使用unite
指定remove = FALSE
来保留初始列以及spread
>
library(dplyr)
library(tidyr)
library(stringr)
df %>%
mutate(type = str_replace(type, "t{2,}", "t")) %>%
unite(new_name, Name, eval, test, remove = FALSE) %>%
spread(type, score)
# new_name Name eval test postest pretest
#1 Jane_first_1 Jane first 1 20 40
#2 Jane_first_2 Jane first 2 20 10
#3 John_first_1 John first 1 15 10
#4 John_first_2 John first 2 30 20
#5 John_second_1 John second 1 50 35
#6 John_second_2 John second 2 10 5
在新版本tidyr_1.0.0
中,引入了pivot_wider
,它可以用作spread
的更广义版本(以后将不推荐使用)。因此,使用
spread
行
...%>%
pivot_wider(names_from = type, values_from = score)
答案 1 :(得分:2)
怎么样……...
data <- tibble(
Name = c(rep("John", 8), rep("Jane", 4)),
eval = c(rep("first", 4), rep("second", 4), rep("first", 4)),
type = rep(c("pretest", "posttest"), 6),
score = c(10, 15, 20, 30, 35, 50, 5, 10, 40, 20, 10, 20)
)
data %>%
group_by(Name, eval, type) %>%
mutate(num = 1:n(),
new_name = str_c(Name, "_", eval, "_", num)) %>%
ungroup() %>%
dplyr::select(new_name, type, score) %>%
spread(type, score)
哪种产量:
# A tibble: 6 x 3
new_name posttest pretest
<chr> <dbl> <dbl>
1 Jane_first_1 20 40
2 Jane_first_2 20 10
3 John_first_1 15 10
4 John_first_2 30 20
5 John_second_1 50 35
6 John_second_2 10 5