【问题标题】:applying simple function to data对数据应用简单函数
【发布时间】:2018-04-17 22:49:58
【问题描述】:

您好,我尝试对数据应用简单函数来为组创建sub_id

test = data.frame(gr=gl(2,4), id =rep(c("Good","bad","ugly","dirty"),2),
                        count=c(175,1,13,11, 10,165,10,2))  


> test
  gr    id count
1  1  Good   175
2  1   bad     1
3  1  ugly    13
4  1 dirty    11
5  2  Good    10
6  2   bad   165
7  2  ugly    10
8  2 dirty     2

sub_id 的条件是这样的

如果组号等于最小值countid==bad,则这些组的 sub_id 为red flag 否则(不满足此条件的其他组)green flag

所以我写了这个函数

  sub_id <- function(gr,count,id){
    if (gr==min(count)&id=="bad"){
      "red flag"

    }
    else
    "green flag"  
  }

试过了

library(dplyr)

  test%>%
    group_by(gr)%>%
    mutate(color=sub_id(gr,count,id))

给我

# A tibble: 8 x 4
# Groups:   gr [2]
      gr     id count      color
  <fctr> <fctr> <dbl>      <chr>
1      1   Good   175 green flag
2      1    bad     1 green flag
3      1   ugly    13 green flag
4      1  dirty    11 green flag
5      2   Good    10 green flag
6      2    bad   165 green flag
7      2   ugly    10 green flag
8      2  dirty     2 green flag
Warning messages:
1: In if (gr == min(count) & id == "Bad") { :
  the condition has length > 1 and only the first element will be used
2: In if (gr == min(count) & id == "Bad") { :
  the condition has length > 1 and only the first element will be used

预期输出

      gr     id count      color
  <fctr> <fctr> <dbl>      <chr>
1      1   Good   175   red flag
2      1    bad     1   red flag
3      1   ugly    13   red flag
4      1  dirty    11   red flag
5      2   Good    10 green flag
6      2    bad   165 green flag
7      2   ugly    10 green flag
8      2  dirty     2 green flag

【问题讨论】:

  • 你能解释一下你的情况吗?如果第二行数等于 2 怎么办?那么第 5 到 8 行会被标记为红色?
  • R 也是区分大小写的。在您的 id 变量中,bad 是小写字母,而在您的 if 条件中,它是大写 b Bad
  • @Masoud 就是这么简单。我只关心组号是否等于最小countid==bad。然后当我们对数据进行分组时,满足此条件的组是 red flag 否则 green flag
  • @JilberUrbina 哦,对不起,我更正了!
  • 最小 countid==bad 我不清楚。对于带有id==bad 的行,您想要count 的最小值吗?所以假设我们有一行 id==badcount==0 那么一切都会被标记为绿色?

标签: r if-statement dplyr


【解决方案1】:

以下内容重现了您的预期输出。

test %>%
    group_by(gr) %>%
    mutate(colour = case_when(
        any(id == "bad" & gr == pmin(count)) ~ "red flag",
        TRUE ~ "green flag"
    ))
## A tibble: 8 x 4
## Groups:   gr [2]
#  gr    id    count colour
#  <fct> <fct> <dbl> <chr>
#1 1     Good   175. red flag
#2 1     bad      1. red flag
#3 1     ugly    13. red flag
#4 1     dirty   11. red flag
#5 2     Good    10. green flag
#6 2     bad    165. green flag
#7 2     ugly    10. green flag
#8 2     dirty    2. green flag

解释:我们按gr 分组,然后使用case_when 标记组内的所有条目,如果组内有id == "bad"gr == min(count),则使用"red flag"

请注意,我们需要使用矢量化pmin(而不是标量min)。


更新

使用用户自定义函数:

sub_id <- function(gr, count, id) {
    ifelse(any(gr == pmin(count) & id == "bad"), "red flag", "green flag")
}
test %>%
    group_by(gr) %>%
    mutate(colour = sub_id(gr, count, id))

【讨论】:

  • 这真的很容易,就像您所做的或使用 ifelse 一样,但 OP 表示希望解决方案具有用户定义的功能。干杯。
  • @Masoud 它一样简单;只需将整个内容包装在一个函数中。不知道是什么问题。
  • @Alexander 不客气。我添加了一个更新来解决您的评论;请看一下。
  • @Alexander 你需要 vectorised pmin 而不是 scalar min。只需逐步检查第一组的条件:pmin(gr == count) 返回c(FALSE, TRUE, FALSE, FALSE)id == "bad" 返回c(FALSE, TRUE, FALSE, FALSE);两个条件的向量化逻辑与给出c(FALSE, TRUE, FALSE, FALSE)any,然后返回整体TRUE。这样就清楚了吗?
  • @Alexander 完全没问题。很高兴它清理了一切:-)
猜你喜欢
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 2011-12-31
  • 1970-01-01
相关资源
最近更新 更多