R: Spread data.frame/tibble 使用共享密钥和缺失数据
R: Spread data.frame/tibble with shared keys and missing data
我有一个两栏 table,我想展开。我知道这是一个非常受欢迎且经过充分探索的主题,但是,我尝试了几种方法但没有得到我想要的。欢迎任何建议和投诉。
我的table里面装满了三个女人的数据。总共有 5 个类别,一般来说,每个类别都充满了价值。但是一些女性的数据缺失,导致整行缺失的原因 - 请注意 Jane
缺失有关 weight
的信息。
a = data.frame(categories = c("name", "sex", "age", "weight", "high",
"name", "sex", "age", "high",
"name", "sex", "age", "weight", "high"),
values = c("Emma", "female", "32", "72", "175",
"Jane", "female", "28", "165",
"Emma", "female", "42", "63", "170"))
categories values
1 name Emma
2 sex female
3 age 32
4 weight 72
5 high 175
6 name Jane
7 sex female
8 age 28
9 high 165
10 name Emma
11 sex female
12 age 42
13 weight 63
14 high 170
我想从 categories
- 列和 values
- 行中获取。但是主要有两个问题:
1) 密钥是共享的 - 两个 Emmas(因此我不能使用 spread
或 reshape
)
2) 某些类别可能会丢失 - 例如 Jane 的体重(因此我不能使用 pivot
或 split
)
最后,我想重塑数据以获得这样的 table:
name sex age weight high
Emma female 32 72 175
Jane female 28 NA 165
Emma female 42 63 170
假设每个条目始终存在 'name'
,我们可以创建一个标识符列并使用 pivot_wider
进行整形。
library(dplyr)
a %>%
group_by(grp = cumsum(categories == 'name')) %>%
tidyr::pivot_wider(names_from = categories, values_from = values) %>%
ungroup %>%
select(-grp)
# name sex age weight high
# <chr> <chr> <chr> <chr> <chr>
#1 Emma female 32 72 175
#2 Jane female 28 NA 165
#3 Emma female 42 63 170
data.table
中的相同逻辑:
library(data.table)
dcast(setDT(a), cumsum(categories == 'name')~categories, value.var = 'values')
假设所有条目都以 name
开头,并在基数 R 中使用 magrittr
进行清洁:
library(magrittr)
split(a, cumsum(a$categories == "name")) %>%
lapply(function(x) setNames(x[[2L]], x[[1L]])[unique(a$categories)]) %>%
do.call(rbind, .) %>%
data.frame()
name sex age weight high
1 Emma female 32 72 175
2 Jane female 28 <NA> 165
3 Emma female 42 63 170
同样玩 data.table
:
library(data.table)
split(a, cumsum(a$categories == "name")) %>%
lapply(transpose, make.names = "categories") %>%
rbindlist(fill = TRUE)
我有一个两栏 table,我想展开。我知道这是一个非常受欢迎且经过充分探索的主题,但是,我尝试了几种方法但没有得到我想要的。欢迎任何建议和投诉。
我的table里面装满了三个女人的数据。总共有 5 个类别,一般来说,每个类别都充满了价值。但是一些女性的数据缺失,导致整行缺失的原因 - 请注意 Jane
缺失有关 weight
的信息。
a = data.frame(categories = c("name", "sex", "age", "weight", "high",
"name", "sex", "age", "high",
"name", "sex", "age", "weight", "high"),
values = c("Emma", "female", "32", "72", "175",
"Jane", "female", "28", "165",
"Emma", "female", "42", "63", "170"))
categories values
1 name Emma
2 sex female
3 age 32
4 weight 72
5 high 175
6 name Jane
7 sex female
8 age 28
9 high 165
10 name Emma
11 sex female
12 age 42
13 weight 63
14 high 170
我想从 categories
- 列和 values
- 行中获取。但是主要有两个问题:
1) 密钥是共享的 - 两个 Emmas(因此我不能使用 spread
或 reshape
)
2) 某些类别可能会丢失 - 例如 Jane 的体重(因此我不能使用 pivot
或 split
)
最后,我想重塑数据以获得这样的 table:
name sex age weight high
Emma female 32 72 175
Jane female 28 NA 165
Emma female 42 63 170
假设每个条目始终存在 'name'
,我们可以创建一个标识符列并使用 pivot_wider
进行整形。
library(dplyr)
a %>%
group_by(grp = cumsum(categories == 'name')) %>%
tidyr::pivot_wider(names_from = categories, values_from = values) %>%
ungroup %>%
select(-grp)
# name sex age weight high
# <chr> <chr> <chr> <chr> <chr>
#1 Emma female 32 72 175
#2 Jane female 28 NA 165
#3 Emma female 42 63 170
data.table
中的相同逻辑:
library(data.table)
dcast(setDT(a), cumsum(categories == 'name')~categories, value.var = 'values')
假设所有条目都以 name
开头,并在基数 R 中使用 magrittr
进行清洁:
library(magrittr)
split(a, cumsum(a$categories == "name")) %>%
lapply(function(x) setNames(x[[2L]], x[[1L]])[unique(a$categories)]) %>%
do.call(rbind, .) %>%
data.frame()
name sex age weight high
1 Emma female 32 72 175
2 Jane female 28 <NA> 165
3 Emma female 42 63 170
同样玩 data.table
:
library(data.table)
split(a, cumsum(a$categories == "name")) %>%
lapply(transpose, make.names = "categories") %>%
rbindlist(fill = TRUE)