【问题标题】:How to add a row to data frame based on a condition如何根据条件向数据框添加行
【发布时间】:2019-10-06 05:15:59
【问题描述】:

我有一个数据框,我想根据以下条件添加一行。条件是column a 等于C 并且column b 等于3 或5。

这是我的数据框

df <- data.frame(a = c("A", "B", "C", "D", "C", "A", "C", "E"), 
                 b = c(seq(8)), stringsAsFactors = TRUE)

只要条件为TRUE,我想在满足条件add 3 的下方添加一行。我已经尝试了以下

rbind(df, data.frame(a="add", b = "3"))
#     a b
# 1   A 1
# 2   B 2
# 3   C 3
# 4   D 4
# 5   C 5
# 6   A 6
# 7   C 7
# 8   E 8
# 9 add 3

这不是我想要的输出。我想要的输出是

#     a b
# 1   A 1
# 2   B 2
# 3   C 3
# 4 add 3   
# 5   D 4
# 6   C 5
# 7 add 3
# 8   A 6
# 9   C 7
# 10  E 8

我该怎么做?我是R 的新手,感谢您的帮助。

【问题讨论】:

    标签: r dataframe rbind


    【解决方案1】:
    lens = ifelse(df$b %in% c(3, 5) & df$a == "C", 2, 1)
    ind = rep(1:NROW(df), lens)
    df2 = df[ind,]
    df2$a = as.character(df2$a)
    df2$a[cumsum(lens)[which(lens == 2)]] = "add"
    df2$b[cumsum(lens)[which(lens == 2)]] = 3
    df2
    #      a b
    #1     A 1
    #2     B 2
    #3     C 3
    #3.1 add 3
    #4     D 4
    #5     C 5
    #5.1 add 3
    #6     A 6
    #7     C 7
    #8     E 8
    

    【讨论】:

      【解决方案2】:

      使用tidyverse 包的解决方案。

      library(tidyverse)
      
      df2 <- df %>%
        mutate(Group = lag(cumsum(a == "C" & b %in% c(3, 5)), default = FALSE)) %>%
        group_split(Group) %>%
        map_dfr(~ .x %>% bind_rows(tibble(a = "add", b = 3))) %>%
        slice(-n()) %>%
        select(-Group)
      
      df2
      # # A tibble: 10 x 2
      #    a         b
      #    <chr> <dbl>
      #  1 A         1
      #  2 B         2
      #  3 C         3
      #  4 add       3
      #  5 D         4
      #  6 C         5
      #  7 add       3
      #  8 A         6
      #  9 C         7
      # 10 E         8
      

      【讨论】:

      • 谢谢你,我投了赞成票。我需要学习tidyverse,一旦我习惯使用baseR。
      【解决方案3】:

      在base R中,我们可以找出a = "c"和b是3或5的位置。在数据框中重复这些行并将它们替换为所需的值。

      pos <- which(df$a == "C" & df$b %in% c(3, 5))
      df <- df[sort(c(seq(nrow(df)), pos)), ]
      df[seq_along(pos) + pos, ] <- list("add", 3)
      row.names(df) <- NULL
      
      df
      #     a b
      #1    A 1
      #2    B 2
      #3    C 3
      #4  add 3
      #5    D 4
      #6    C 5
      #7  add 3
      #8    A 6
      #9    C 7
      #10   E 8
      

      数据

      df <- data.frame(a = c("A", "B", "C", "D", "C", "A", "C", "E"), 
                       b = c(seq(8)), stringsAsFactors = FALSE)
      

      【讨论】:

        猜你喜欢
        • 2021-06-20
        • 2021-03-02
        • 2021-06-29
        • 2019-08-29
        • 1970-01-01
        • 1970-01-01
        • 2022-11-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多