把 pivot_wider() 变成 spread()

turn pivot_wider() into spread()

我喜欢新的 tidyr pivot_wider 函数,但由于它尚未正式添加到 CRAN 包中,我想知道如何将以下代码转换为旧的 spread()功能(我无法从 github 访问服务器到 DL tidyr

test <- data.frame(x = c(1,1,2,2,2,2,3,3,3,4),
                   y = c(rep("a", 5), rep("b", 5)))


test %>%
  count(x, y) %>%
  group_by(x) %>%
  mutate(prop = prop.table(n)) %>%
  mutate(v1 = paste0(n, ' (', round(prop, 2), ')')) %>%
  pivot_wider(id_cols = x, names_from = y, values_from = v1)

期望的输出:

# A tibble: 4 x 3
# Groups:   x [4]
      x a        b       
  <dbl> <chr>    <chr>   
1     1 2 (1)    NA      
2     2 3 (0.75) 1 (0.25)
3     3 NA       3 (1)   
4     4 NA       1 (1)

我试过了(但不太对):

test %>%
  count(x, y) %>%
  group_by(x) %>%
  mutate(prop = prop.table(n)) %>%
  mutate(v1 = paste0(n, ' (', round(prop, 2), ')')) %>%
  spread(y, v1) %>%
  select(-n, -prop)

感谢任何帮助!

一个选项是删除 spread 语句之前的 'n'、'prop' 列,因为包括它们也会创建具有该列值的唯一行

library(dplyr)
library(tidyr)
test %>%
   count(x, y) %>%
   group_by(x) %>%
   mutate(prop = prop.table(n)) %>%
   mutate(v1 = paste0(n, ' (', round(prop, 2), ')')) %>% 
   select(-n, -prop) %>% 
   spread(y, v1)
# A tibble: 4 x 3
# Groups:   x [4]
#      x a        b       
#  <dbl> <chr>    <chr>   
#1     1 2 (1)    <NA>    
#2     2 3 (0.75) 1 (0.25)
#3     3 <NA>     3 (1)   
#4     4 <NA>     1 (1)   

或使用base R

tbl <- table(test)
tbl[] <- paste0(tbl, "(", prop.table(tbl, 1), ")")

您可以使用 data.table 包:

> library(data.table)
> setDT(test)[,.(n=.N),by=.(x,y)][,.(y=y,n=n,final=gsub('\(1\)','',paste0(n,'(',round(prop.table(n),2), ')'))),by=x]


   x y n   final
1: 1 a 2       2
2: 2 a 3 3(0.75)
3: 2 b 1 1(0.25)
4: 3 b 3       3
5: 4 b 1       1