【问题标题】:How to delete certain condition from data frame如何从数据框中删除某些条件
【发布时间】:2020-10-07 13:48:57
【问题描述】:

假设这是我的 df :

people <- c(1,1,1,2,2,3,3,4,4,5,5)
activity <- c(1,1,1,2,2,3,4,5,5,6,6)
completion <- c(0,0,1,0,1,1,1,0,0,0,1)

我想删除所有从未完成任何活动的人。

我已经尝试过这段代码,但不知何故它不起作用。我不知道这里可能出了什么问题。

nevercompleted<- df %>% 
  filter(completion != 0) %>% 
  group_by(people) %>% 
  summarise("frequency activity" = n())

df<- -c (df$nevercompleted)

因此,在这种情况下,应该从 df 中删除人员 4。请注意,我只对删除那些从未完成任何事情的人感兴趣,例如第 4 个人,而不是曾经完成过某项活动的第 1 个人。

【问题讨论】:

    标签: r variables data-cleaning


    【解决方案1】:

    下面是应该工作的代码:

    library(dplyr)
    
    people <- c(1,1,1,2,2,3,3,4,4,5,5)
    activity <- c(1,1,1,2,2,3,4,5,5,6,6)
    completion <- c(0,0,1,0,1,1,1,0,0,0,1)
    
    df <- data.frame(people, activity, completion)
    
    df <- filter(df, completion != 0)
    

    结果:

      people activity completion
    1      1        1          1
    2      2        2          1
    3      3        3          1
    4      3        4          1
    5      5        6          1
    

    这会将您的数据框过滤到 completion 变量不为 0 的行。

    我不确定您使用group_bysummarize 要去哪里。如果您想要做的不仅仅是删除 completion 变量为 0 的行,请在您的问题中说明这一点。

    【讨论】:

    • 哦,为什么答案比我想的要简单得多。但这是否仍然会让那些在一段时间后完成活动的人像第 1 个人一样。我有面板数据,只想删除那些从未完成任何事情的人
    • 是的,它会的。这里的filter 函数是逐行运行的——它不关心人 1 在其他行中做了什么。将保留第 1 个人对 completion 具有 1 的行。我将结果添加到我的答案中。
    • 运行它时,它几乎删除了我所有的用户..
    • 实际上,我想完成第 1 个人的所有行,如果他们中的任何一个对某个任务有 1 的话
    • 您的结果与我的结果有哪些不同?此解决方案将删除 completion 变量为 0 的所有行。“完成所有行”是什么意思?我有点困惑。
    【解决方案2】:

    1。碱基R

    在基础 R 中,以下内容可以很容易地重写为单行代码。

    i <- ave(as.logical(df$completion), df$people, FUN = function(x) any(x != 0, na.rm = TRUE))
    df <- df[which(i), ]
    df
    #   people activity completion
    #1       1        1          0
    #2       1        1          0
    #3       1        1          1
    #4       2        2          0
    #5       2        2          1
    #6       3        3          1
    #7       3        4          1
    #10      5        6          0
    #11      5        6          1
    

    2。包dplyr

    这是dplyr的方式。

    首先只过滤已完成活动的人,然后加入原始数据集以获取所有列。

    df <- df %>%
      group_by(people) %>%
      summarise(completion = any(as.logical(completion))) %>%
      filter(completion) %>%
      select(-completion) %>%
      left_join(df, by = 'people')
    
    df
    #`summarise()` ungrouping output (override with `.groups` argument)
    ## A tibble: 9 x 3
    #  people activity completion
    #   <dbl>    <dbl>      <dbl>
    #1      1        1          0
    #2      1        1          0
    #3      1        1          1
    #4      2        2          0
    #5      2        2          1
    #6      3        3          1
    #7      3        4          1
    #8      5        6          0
    #9      5        6          1
    

    数据

    问题中没有data.frame 指令,只有列向量的创建。

    people <- c(1,1,1,2,2,3,3,4,4,5,5)
    activity <- c(1,1,1,2,2,3,4,5,5,6,6)
    completion <- c(0,0,1,0,1,1,1,0,0,0,1)
    df <- data.frame(people, activity, completion)
    

    【讨论】:

    • @DanielO 是的。为了便于阅读,我更喜欢这样发帖。
    • 这很公平。您可以通过使用 with 命令删除来使其更易于阅读,尤其是因为 df 无论如何只被引用一次。 ave(as.logical(df$completion), people, FUN = function(x) any(x != 0))
    • 不知何故它没有从我的 df 中删除,我需要添加一些东西来删除它们还是代码已经包含它?
    • @Leah 除非您将结果分配给它,否则不会从 df 中删除任何内容,df &lt;- code
    • @DanielO 你是对的,已编辑。 (但我也编码了df$people)。
    【解决方案3】:

    在 Base 中我们可以这样做

        byGroup <- split(df,df$people)
        do.call(rbind,byGroup[sapply(byGroup, function(x) !all(x$completion == 0))])
    
          people activity completion
    1.1       1        1          0
    1.2       1        1          0
    1.3       1        1          1
    2.4       2        2          0
    2.5       2        2          1
    3.6       3        3          1
    3.7       3        4          1
    5.10      5        6          0
    5.11      5        6          1
    

    【讨论】:

    • 请注意,我只想删除那些从未完成过任何事情的人,例如第 4 个人,第 1 个人在某一时刻完成了活动。
    • @Leah,我的回答就是这样,只有第 4 个人被删除了。所有其他条目仍然存在。
    • 哦,完美!我会重新运行你的答案,看看它是否有效:)
    • 我得到输出 NULL 并且 df 没有任何变化,这意味着什么?
    • 你能解释一下为什么我得到这个输出吗?
    【解决方案4】:

    可以这样做

    library(tidyverse)
    df <- tibble(people, activity, completion)
    
    df %>% 
      group_by(people) %>% 
      filter(any(completion != 0))
    
    # A tibble: 9 x 3
    # Groups:   people [4]
      people activity completion
       <dbl>    <dbl>      <dbl>
    1      1        1          0
    2      1        1          0
    3      1        1          1
    4      2        2          0
    5      2        2          1
    6      3        3          1
    7      3        4          1
    8      5        6          0
    9      5        6          1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-02
      • 2022-08-05
      • 1970-01-01
      • 1970-01-01
      • 2021-04-22
      • 1970-01-01
      相关资源
      最近更新 更多