使用dplyr和tidyr从长格式转换为宽格式时出现意外行

时间:2017-11-19 13:54:30

标签: r

我有一个数据框(dfdat),有两个分类变量,位置和就业状态。

我想生成一个数据框,其中包含每个地点的就业状况比例。

mydf_wide(实现的结果)几乎就是我正在寻找的。问题是jobsstatus是一个有两个级别的变量,但mydf_wide中有三行。我不明白为什么会这样,因为我已经期待类似于mytable(预期结果)的东西。

非常感谢任何帮助。

起点(df):

dfdat <- data.frame(location=c("GA","GA","MA","OH","RI","GA","AZ","MA","OH","RI"),employmentstatus=c(1,2,1,2,1,1,1,2,1,1))

预期结果(表):

mytable <- table(dfdat$employmentstatus,dfdat$location)
mytable <- round(100*(prop.table(mytable, 2)),1)

达成结果(df):

library(dplyr)
mydf <- dfdat  %>%
group_by(location,employmentstatus) %>%
summarise (n = n()) %>%
mutate(freq = round((n / sum(n)*100),1))

library(tidyr)
mydf_wide <- spread(mydf, location, freq)
mydf_wide <- as.data.frame(mydf_wide)

1 个答案:

答案 0 :(得分:0)

我们需要使用'location'做第二个group_by来获取sum。此外,不是分组然后创建'n',而是可以使用count函数

dfdat %>%
    count(location, employmentstatus) %>%
    group_by(location) %>% 
    mutate(n = round(100*n/sum(n), 2)) %>%
    spread(location, n, fill = 0)
# A tibble: 2 x 6
#  employmentstatus    AZ    GA    MA    OH    RI
#*            <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1                1   100 66.67    50    50   100
#2                2     0 33.33    50    50     0

如果我们使用OP的代码,请删除“n”列,然后执行spread

dfdat %>%
    group_by(location,employmentstatus) %>%
    summarise (n = n())  %>%
    mutate(freq = round((n / sum(n)*100),1)) %>% 
    select(-n) %>%
    spread(location, freq, fill =0)

或使用round的输出更新'n'列,然后spread。 'n'中的额外列确保数据集中存在组合