把pivot_wider()变成spread()

时间:2019-11-21 19:06:17

标签: r tidyr 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)

任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:3)

一种选择是删除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), ")")

答案 1 :(得分:2)

您可以使用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