tidyverse使用重复的关键点进行排列,并基于唯一的关键点填充NAs

tidyverse使用重复的关键点进行排列,并基于唯一的关键点填充NAs,r,dplyr,tidyr,tidyverse,R,Dplyr,Tidyr,Tidyverse,考虑一个最小的例子: library(tidyverse) ex <-tribble( ~id, ~property, ~value, 1, "A", 9, 1, "A", 8, 1, "B", 7, 2, "A", 6, 2, "B", 5 ) 按id和property分组并添加一个键会很接近,但会留下NA: ## almost but not quite ex %>%

考虑一个最小的例子:

library(tidyverse)
ex <-tribble(
  ~id, ~property, ~value,
  1,    "A",      9,
  1,    "A",      8,
  1,    "B",      7,
  2,    "A",      6,
  2,    "B",      5
)
id
property
分组并添加一个键会很接近,但会留下NA:

## almost but not quite
ex %>% 
  group_by(id, property) %>%
  mutate(key = row_number()) %>%
  spread(property, value) %>% 
  select(-key) -> X
X
给出:

     id     A     B
1     1     9     7
2     1     8    NA
3     2     6     5
我可以在最简单的示例中解决这个问题,方法是按每个
属性拆分上述内容,删除NAs,然后按
id
重新连接:

inner_join(
  na.omit(select(X, id, A)),
  na.omit(select(X, id, B))
)
但很明显,这并不能推广到任意属性集。有什么更好的
tidyverse
策略可以做到这一点


注意:前面的几个问题说明了这一部分的前半部分,例如,构建
列,以便
排列
不会失败,但看不到解决
NA的内容

您可以从
tidyr
使用
fill

library(dplyr)
library(tidyr)

ex %>% 
  group_by(id, property) %>%
  mutate(key = row_number()) %>%
  spread(property, value) %>% 
  select(-key) %>%
  group_by(id) %>%
  fill(-id)
结果:

# A tibble: 3 x 3
# Groups:   id [2]
     id     A     B
  <dbl> <dbl> <dbl>
1     1     9     7
2     1     8     7
3     2     6     5
#一个tible:3 x 3
#组别:id[2]
身份证
1     1     9     7
2     1     8     7
3     2     6     5

对于B只有2个值,但是对于A只有3个值,为什么您不希望它为B提供一个
NA
?您只是想用前面的值填充NA吗?@useR,因为我们知道id为1的对象的属性B基于id为1的其他行。本质上,属性A可以是多值的(想想id为1的纸张可以有多个“关键字”(属性A),每个关键字都出现在单独的一行中,bc我不喜欢表格中的列表值。是的,但是为什么你希望程序知道呢?当id1中只有一个“B”而只有两个“A”时例如,按
id
property
分组时生成的键对于“A”的两个值将具有
1
2
,但对于“B”仅具有
1
。这会在展开时为B创建一个缺少的值,因为“B”没有
key==2
.fill很好,但它看起来不是基于id,而是基于下一行或上一行。这似乎非常脆弱——即使先按id排序,我们也无法确定始终是具有相同id的行。@cboettig您可以始终
group\u by(id)
。请参阅我的编辑。我想它实际上已经按照
id
进行了分组。在本例中,很高兴知道fill尊重组
# A tibble: 3 x 3
# Groups:   id [2]
     id     A     B
  <dbl> <dbl> <dbl>
1     1     9     7
2     1     8     7
3     2     6     5