代码之家  ›  专栏  ›  技术社区  ›  Tito Sanz

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

  •  0
  • Tito Sanz  · 技术社区  · 7 年前

    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 在所有的行中
    • 如果同一用户有 vegetables 在所有的行中 蔬菜
    • 如果同一用户有 蔬菜 和/或 水果 得到 mix

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

    到目前为止,我已经尝试应用一个自定义函数,但是由于中的每个用户没有确切的行数 x 我想不出一个合适的解决办法。使用 tidyverse溶液

    3 回复  |  直到 7 年前
        1
  •  2
  •   A. Suliman    7 年前
    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
    
        2
  •  1
  •   Rich Scriven    7 年前

    滚动将值与因子级别进行比较的函数,然后进行聚合。

    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
    
        3
  •  0
  •   lebatsnok    7 年前

    tapply

    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
    
    推荐文章