创建样本数据集以重现问题
library(dplyr)
x <- c('MS','Google','MS','FB','Amazon','Google','IBM','IBM','IBM','MS')
item <- as.data.frame(x,stringsAsFactors = F)
data <- item %>% group_by(x) %>% summarise(n = n())
# A tibble: 5 x 2
x n
<chr> <int>
1 Amazon 1
2 FB 1
3 Google 2
4 IBM 3
5 MS 3
现在我打算创建一个数据集,其中所有'n'计数小于2应该在一行中总结为'other',同时它也将n计数总和为
x n
<chr> <int>
1 Other 2
2 Google 2
3 IBM 3
4 MS 3
我可以通过下面提到的代码来实现它,但我确定这不是很好的方法,如果我可以通过dplyr查询直接做同样的建议我
data$x[data$n < 2]= 'Other'
data <- aggregate(n~x, data, FUN = sum)
答案 0 :(得分:4)
以下是dplyr
,
library(dplyr)
data %>%
mutate(grp = cumsum(c(1, diff(n < 2) != 0)),
grp = replace(grp, n >=2, grp[n >= 2] + row_number()[n >= 2])) %>%
group_by(grp) %>%
summarise(x = toString(x), n = sum(n)) %>%
ungroup() %>%
select(-grp)
给出,
# A tibble: 4 x 2 x n <chr> <int> 1 Amazon, FB 2 2 Google 2 3 IBM 3 4 MS 3
注意:如果您真的想使用Other
,那么在管道的末尾添加以下内容,
... %>% mutate(x = replace(x, grepl(',', x), 'Other'))
解读&#39;分组的cumsum
部分可以将其分解。
我们希望创建一个组,其中该组中的所有值都小于2.但是,我们也不可避免地为大于(或等于)2的值创建组。为了避免汇总这些组,我们通过添加来替换它们它们的增量值。这将确保值大于2的组只有一个元素,从而确保它们不会在最后得到汇总。
获取组的技巧是创建一个值小于2的逻辑向量,并使用差异来查找何时从TRUE变为FALSE(因此...!= 0
部分)。由于diff
会删除某个值,因此我们会c(1, diff(...))
手动添加它。请注意,您可以放置TRUE
而不是1。 cumsum
然后创建组。为了避免总结具有值> gt的组。 2,我们通过将row_number添加到它们来替换它们。为什么row_number?因为它增加,从而使所有群体都独一无二。
x <- c(1, 1, 3, 4, 2, 1, 1, 1, 5)
x < 2
#[1] TRUE TRUE FALSE FALSE FALSE TRUE TRUE TRUE FALSE
diff(x < 2) != 0
#[1] FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE
cumsum(c(1, diff(x < 2) != 0))
#[1] 1 1 2 2 2 3 3 3 4
答案 1 :(得分:2)
我们还可以在case_when
中使用group_by
来更改&#39; x&#39;价值与其他&#39;在哪里&#39; n&#39;是1然后执行sum
的&#39; n&#39;在summarise
library(dplyr)
data %>%
group_by(x = case_when(n ==1 ~ 'Other',
TRUE ~ x)) %>%
summarise(n = sum(n))
# A tibble: 4 x 2
# x n
# <chr> <int>
#1 Google 2
#2 IBM 3
#3 MS 3
#4 Other 2
答案 2 :(得分:1)
使用bind_rows
和filter
作为另一种选择:
library(dplyr)
x <- c('MS','Google','MS','FB','Amazon','Google','IBM','IBM','IBM','MS')
item <- as.data.frame(x,stringsAsFactors = F)
data <- item %>% group_by(x) %>% summarise(n = n())
data %>% {
bind_rows(filter(., n >= 2),
filter(., n < 2) %>% summarise(x = "Other", n = sum(n))
)
}
# x n
# <chr> <int>
#1 Google 2
#2 IBM 3
#3 MS 3
#4 Other 2