【问题标题】:Working with Tidyverse and the base R function ´ Which´使用 Tidyverse 和基本 R 函数“哪个”
【发布时间】:2021-09-28 23:54:41
【问题描述】:

你好可爱的 SO 我希望你玩得开心,我一直在使用 Base R 函数“Which”来处理序列非常有趣,但在更大范围内,我很快就会使用 tidyverse 来做一些数据争吵,我似乎无法找到将这些功能与 tidyverse 合并的方法。让我解释一下我想做什么:

我有以下数据集

STUDENT EVENT
James GEO_EXAM
James PIZZA_PARTY
Kylie MATH_EXAM
Kylie PIZZA_PARTY
Laura MATH_EXAM
Mark MATH_EXAM
Mark PIZZA_PARTY

我希望能够对事件进行排序(为简单起见,这些事件按所需的顺序排列)然后按学生分组并找到最后一个事件或最后一个事件或每组学生是什么在 PIZZA_PARTY 之前(我们将假设顺序从上到下),我拥有的数据集被过度简化以说明这种情况。

前面的数据集已经说过,对于 James 来说,PIZZA_PARTY 之前的事件是 GEO 考试,Kylie 是数学考试,Laura 在 PIZZA_PARTY 之前没有事件,最后是 Mark it是数学考试。这将是理想的结果。

但如果我忽略了我确实想通过 STUDENTS 解决这个 excersie 分组的事实,我可以轻松使用以下代码开始

df$EVENT[which(df$EVENT=="PIZZA_PARTY")-1]

但如果我想以我想要的方式使用 tidyverse 来解决这个问题:

df %>% 
  group_by(STUDENT) %>% 
  mutate(INDEX=(which(EVENT=="PIZZA_PARTY")-1))

但是我得到一个错误,当我使用summary时我也得到一个错误,我觉得我在碰壁,所以非常感谢你们,如果你们能指导我或者让我有什么文献、博客或书籍应该查看以了解如何在 tidyverse 中正确使用基本 R 函数,或者请参考一些对解决此问题有用的链接或博客,非常感谢

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    问题是当我们有一个缺少值的组时,即“劳拉”,没有PIZZA_PARTY

    > subset(df, STUDENT == "Laura" & EVENT == "PIZZA_PARTY")
    [1] STUDENT EVENT  
    <0 rows> (or 0-length row.names)
    

    因此返回logical(0)。在mutate 中,它需要与行数相同的输出长度(或者如果它被分组,长度应该匹配相同数量的组元素)。请注意,即使是重复的值也可能导致相同的错误。所以,最好获取第一个可用值的索引

    library(dplyr)
    df %>% 
      group_by(STUDENT) %>% 
      mutate(INDEX=which(EVENT == "PIZZA_PARTY")[1]-1)
    

    -输出

    # A tibble: 7 × 3
    # Groups:   STUDENT [4]
      STUDENT EVENT       INDEX
      <chr>   <chr>       <dbl>
    1 James   GEO_EXAM        1
    2 James   PIZZA_PARTY     1
    3 Kylie   MATH_EXAM       1
    4 Kylie   PIZZA_PARTY     1
    5 Laura   MATH_EXAM      NA
    6 Mark    MATH_EXAM       1
    7 Mark    PIZZA_PARTY     1
    

    或者另一种选择是也使用match

    df %>%
        group_by(STUDENT) %>%
        mutate(INDEX = match("PIZZA_PARTY", EVENT) - 1)
    

    如果我们需要这个来创建一个带有相应 'EVENT' 的 RESPONSE 变量

    df %>%  
          group_by(STUDENT) %>% 
          mutate(RESPONSE = EVENT[match("PIZZA_PARTY", EVENT) - 1])
    

    -输出

    # A tibble: 7 × 3
    # Groups:   STUDENT [4]
      STUDENT EVENT       EVENTNEW 
      <chr>   <chr>       <chr>    
    1 James   GEO_EXAM    GEO_EXAM 
    2 James   PIZZA_PARTY GEO_EXAM 
    3 Kylie   MATH_EXAM   MATH_EXAM
    4 Kylie   PIZZA_PARTY MATH_EXAM
    5 Laura   MATH_EXAM   <NA>     
    6 Mark    MATH_EXAM   MATH_EXAM
    7 Mark    PIZZA_PARTY MATH_EXAM
    

    数据

    df <- structure(list(STUDENT = c("James", "James", "Kylie", "Kylie", 
    "Laura", "Mark", "Mark"), EVENT = c("GEO_EXAM", "PIZZA_PARTY", 
    "MATH_EXAM", "PIZZA_PARTY", "MATH_EXAM", "MATH_EXAM", "PIZZA_PARTY"
    )), class = "data.frame", row.names = c(NA, -7L))
    

    【讨论】:

    • 你太棒了,谢谢你,就像你不知道一样,非常感谢我有一个最后一个问题,恕我直言,我想使用存储在变量 INDEX 中的那个数字来提取相应的事件按组,但是当我尝试使用 [] 这样做时,我现在得到一个错误,你知道正确的方法是什么吗?例如,你惊人的代码说,对于詹姆斯组,披萨派对之前的事件在索引 1 中我如何在名为“响应”的变量中检索该特定事件的名称,非常感谢我的朋友,就像你不知道多少意思!
    • 您可能需要df %&gt;% group_by(STUDENT) %&gt;% mutate(RESPONSE = EVENT[match("PIZZA_PARTY", EVENT) - 1])
    • @R_Student 你想要更新中的输出吗
    • 很抱歉,我没有看到它,你很友善@Akrun,你的回答无可挑剔,非常感谢你
    • 非常感谢我的朋友,从心底里谢谢你
    【解决方案2】:

    您可以使用lead 来获取下一个事件是'PIZZA_PARTY' 之后的事件。

    library(dplyr)
    
    df %>%
      group_by(STUDENT) %>%
      summarise(last_event = EVENT[lead(EVENT == 'PIZZA_PARTY', default = FALSE)])
    
    #  STUDENT last_event
    #  <chr>   <chr>     
    #1 James   GEO_EXAM  
    #2 Kylie   MATH_EXAM 
    #3 Mark    MATH_EXAM 
    

    【讨论】:

    • 这实际上取决于您希望输出的方式。 summarise 通常每组只保留 1 行(STUDENT 此处)。 mutate 将保持相同的行数。
    猜你喜欢
    • 2021-10-14
    • 2023-03-13
    • 2021-04-20
    • 2021-05-30
    • 2012-07-29
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    相关资源
    最近更新 更多