【问题标题】:R - Return column name for row where first given value is foundR - 返回找到第一个给定值的行的列名
【发布时间】:2020-11-17 21:59:43
【问题描述】:

我正在尝试在数据框中 为每一行值找到 FALSE 的第一次出现。我的行是特定的事件,列是日期。我希望能够找到第一个 FALSE 的日期,以便我可以使用该值来查找返回日期。

我的数据框的示例结构:

df <- data.frame(ID = c(1,2,3), '2001' = c(TRUE, TRUE, TRUE), 
                 '2002' = c(FALSE, TRUE, FALSE), '2003' = c(TRUE, FALSE, TRUE))

我希望得到第二个数据框或列表,其中包含标识第一个 FALSE 实例的 ID 和列名。

例如:

ID | Date
1  | 2002
2  | 2003
3  | 2002

我不知道找到这种结果的机制。

实际的数据框包含几千行,所以很遗憾我无法手动完成。

我是新的 R 用户,所以请不要建议您可能期望更有经验的 R 用户已经考虑过的事情。

提前致谢

【问题讨论】:

    标签: r dataframe data-manipulation find-occurrences rowwise


    【解决方案1】:

    使用tidyverse 函数试试这个。您可以将数据重新整形为 long,然后过滤 F 值。如果有一些重复的行,第二个过滤器可以避免它们。代码如下:

    library(dplyr)
    library(tidyr)
    #Code
    newdf <- df %>% pivot_longer(-ID) %>%
      group_by(ID) %>%
      filter(value==F) %>%
      filter(!duplicated(value)) %>% select(-value) %>%
      rename(Myname=name)
    

    输出:

    # A tibble: 3 x 2
    # Groups:   ID [3]
         ID Myname 
      <dbl> <chr>
    1     1 2002 
    2     2 2003 
    3     3 2002 
    

    另一个没有重复值的选项可以使用row_number() 来提取第一个值(row_number()==1):

    library(dplyr)
    library(tidyr)
    #Code 2
    newdf <- df %>% pivot_longer(-ID) %>%
      group_by(ID) %>%
      filter(value==F) %>%
      mutate(V=ifelse(row_number()==1,1,0)) %>%
      filter(V==1) %>%
      select(-c(value,V)) %>% rename(Myname=name)
    

    输出:

    # A tibble: 3 x 2
    # Groups:   ID [3]
         ID Myname 
      <dbl> <chr>
    1     1 2002 
    2     2 2003 
    3     3 2002 
    

    或者将base Rapply() 和一个通用函数一起使用:

    #Code 3
    out <- data.frame(df[,1,drop=F],Res=apply(df[,-1],1,function(x) names(x)[min(which(x==F))]))
    

    输出:

      ID  Res
    1  1 2002
    2  2 2003
    3  3 2002
    

    【讨论】:

    • 非常感谢!真正的救星。如何将更改结果列的名称合并到新数据框中?它默认为“名称”。 (我知道如何在事后更改列名,但我很好奇您将如何将其合并到您提供的代码中。
    • @JMade 我已经更新了解决方案。您必须使用 rename() 并分配所需的名称。希望对您有所帮助!
    • 我发布了另一个问题,您可能对此有所了解:link@Duck
    【解决方案2】:

    我们可以在反转逻辑值后使用max.colties.method = 'first'

    cbind(df[1], Date = names(df[-1])[max.col(!df[-1], ties.method = 'first')])
    #  ID Date
    #1  1 2002
    #2  2 2003
    #3  3 2002
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      • 1970-01-01
      相关资源
      最近更新 更多