基于tidydata格式的非精确数量的分类值的新变量

时间:2018-08-23 21:32:15

标签: r dplyr tidyverse

尝试根据整理数据中的几种分类条件创建新变量。这是我的数据的示例:

d <- data.frame(
  x = c("a", "a", "b", "b", "b", "c", "c"),
  y = c("fruit", "fruit", "vegetables", "fruit", "vegetables", "vegetables", "vegetables")
)

d
#>   x          y
#> 1 a      fruit
#> 2 a      fruit
#> 3 b vegetables
#> 4 b      fruit
#> 5 b vegetables
#> 6 c vegetables
#> 7 c vegetables

创建数据集的条件是:

  • 如果同一用户在所有行中都有fruit,则会得到fruit
  • 如果同一用户在所有行中都有vegetables,则会得到vegetables
  • 如果同一用户拥有vegetables和/或fruit获得mix

因此,所需的输出如下所示:

#>   x          y
#> 1 a      fruit
#> 2 b        mix
#> 3 c vegetables

到目前为止,我已经尝试应用自定义函数,但是由于x列中没有每个用户的确切行数,因此我无法找到合适的解决方案。使用 tidyverse解决方案会很好。

3 个答案:

答案 0 :(得分:2)

library(dplyr)
d %>% mutate_if(is.factor, as.character) %>% 
      group_by(x) %>%
      #Check if number of distinct "unique" for y within x==1, then get the first element of y else return 'mix' 
      summarise(y = ifelse(n_distinct(y) == 1, first(y), 'mix')) 

# A tibble: 3 x 2
  x     y         
<chr> <chr>     
1 a     fruit     
2 b     mix       
3 c     vegetables

答案 1 :(得分:1)

滚动一个将值与因子水平进行比较的函数,然后进行汇总。

f <- function(x) {
    if(all(levels(x) %in% x)) "mix" else unique(levels(x)[x])
}

aggregate(y ~ x, d, f)
#   x          y
# 1 a      fruit
# 2 b        mix
# 3 c vegetables

答案 2 :(得分:0)

使用tapply

的基本r
tapply(d$y, d$x, function(x) if(length(u<-unique(x))==1) u else "mix")
#       a            b            c 
# "fruit"        "mix" "vegetables" 

或者,如果结果的格式很重要:

res <- tapply(d$y, d$x, function(x) if(length(u<-unique(x))==1) u else "mix")
data.frame(x=names(res), y=res)
#   x          y
# a a      fruit
# b b        mix
# c c vegetables