数字之和在数据框中工作,但不在tibble中

问题描述 投票:1回答:1

我想在一个tibble列中添加所有数字作为学习R的练习,并使用示例数据集forcats::gss_cat。我想按年龄来看待婚姻状况:

by_ag <- gss_cat %>%
filter(!is.na(age)) %>%
group_by(age, marital) %>%
count() 
by_age <- by_ag %>%
mutate(prop = n/sum(n))

ggplot(by_age, aes(age, prop, colour = marital)) +
  geom_line(na.rm = TRUE)

这就是我得到的:plot from tibble

显然,计算的比例实际上不是一个比例,因为sum(n)实际上等于n。为了帮助识别问题,我创建了一个小数据框:

df <- data.frame(type = c("new", "old", "don't know"), number = c(20, 12, 34))

并计算了一个比例:

df %>%
  mutate(prop = number/sum(number))

这按预期工作:

# A tibble: 3 x 3
type       number  prop
<chr>       <dbl> <dbl>
1 new          20.0 0.303
2 old          12.0 0.182
3 don't know   34.0 0.515

因此,我将我的初始tibble转换为数据框并重新编写代码:

by_age <- as.data.frame(by_ag) %>%
  mutate(prop = n/sum(n))
ggplot(by_age, aes(age, prop, colour = marital)) +
  geom_line(na.rm = TRUE)

并得到了一个完美的情节:plot from data frame

因此,我最初的结论是,原因是我最初有一个小组。因此,为了检查这个假设,我还创建了一个新的tibble:

df <- tibble(type = c("new", "old", "don't know"), number = c(20, 12, 34))
df %>%
  mutate(prop = number/sum(number))

然后在这里完全混淆,计算工作比例没有问题:

A tibble: 3 x 3
type       number  prop
<chr>       <dbl> <dbl>
1 new          20.0 0.303
2 old          12.0 0.182
3 don't know   34.0 0.515

那么为什么sum(n)在我最初的例子中不起作用?

我想补充一点,这来自R for Data Science(working with factors)的练习,他们没有取消组合:enter image description here那么可能是什么原因呢?

r dataframe sum tibble
1个回答
2
投票

这里'by_ag'是一个分组对象,因此,'n'的sum在每个'组'中进行求和。选项是提取列,即.$n

by_ag %>%
    mutate(prop = n/sum(.$n))

ungroup对象,然后做sum

by_ag %>%
    ungroup %>%
    mutate(prop = n/sum(n))

为了说明差异,使用OP的'df'

df %>%
    group_by(type) %>%
    mutate(Sum = sum(number))
# A tibble: 3 x 3
# Groups: type [3]
#  type       number   Sum
#  <fctr>      <dbl> <dbl>
#1 new          20.0  20.0
#2 old          12.0  12.0
#3 don't know   34.0  34.0

df %>% 
    group_by(type) %>%
    mutate(Sum = sum(.$number))
# A tibble: 3 x 3
# Groups: type [3]
#  type       number   Sum
#  <fctr>      <dbl> <dbl>
#1 new          20.0  66.0
#2 old          12.0  66.0
#3 don't know   34.0  66.0

根据OP的评论,练习here使用单个分组变量,在summarise之后被剥离

relig_summary <- gss_cat %>%
   group_by(relig) %>%
   summarise(
     age = mean(age, na.rm = TRUE),
     tvhours = mean(tvhours, na.rm = TRUE),
     n = n()
   )

str(relig_summary)
#Classes ‘tbl_df’, ‘tbl’ and 'data.frame':       15 obs. of  4 variables:
# $ relig  : Factor w/ 16 levels "No answer","Don't know",..: 1 2 3 4 5 6 7 8 9 10 ...
# $ age    : num  49.5 35.9 40 38.9 40.1 ...
# $ tvhours: num  2.72 4.62 2.87 3.46 2.79 ...
# $ n      : int  93 15 109 23 689 95 104 32 71 147 ...

而不是一个分组变量,我们添加两个,

by_ag <- gss_cat %>%
            filter(!is.na(age)) %>%
            group_by(age, marital) %>%
            count()    

str(by_ag) #check the grouped_df class
#Classes ‘grouped_df’, ‘tbl_df’, ‘tbl’ and 'data.frame': 351 obs. of  3 variables:
# $ age    : int  18 18 19 19 19 19 20 20 20 20 ...
# $ marital: Factor w/ 6 levels "No answer","Never married",..: 2 6 2 4 5 6 2 3 4 6 ...
# $ n      : int  89 2 234 3 1 11 227 1 2 21 ...
# - attr(*, "vars")= chr  "age" "marital"
# - attr(*, "drop")= logi TRUE
# - attr(*, "indices")=List of 351

当我们转换为data.frame时,分组属性将丢失

as.data.frame(by_ag) %>% 
           str
#'data.frame':   351 obs. of  3 variables:
#$ age    : int  18 18 19 19 19 19 20 20 20 20 ...
#$ marital: Factor w/ 6 levels "No answer","Never married",..: 2 6 2 4 5 6 2 3 4 6 ...
#$ n      : int  89 2 234 3 1 11 227 1 2 21 ...

ungroup相似

by_ag %>% 
     ungroup %>% 
     str
#Classes ‘tbl_df’, ‘tbl’ and 'data.frame':       351 obs. of  3 variables:
# $ age    : int  18 18 19 19 19 19 20 20 20 20 ...
# $ marital: Factor w/ 6 levels "No answer","Never married",..: 2 6 2 4 5 6 2 3 4 6 ...
# $ n      : int  89 2 234 3 1 11 227 1 2 21 ...
© www.soinside.com 2019 - 2024. All rights reserved.