【问题标题】:R - Make new column and fill based on cell value between two delimiterR - 根据两个分隔符之间的单元格值创建新列并填充
【发布时间】:2019-12-05 15:57:00
【问题描述】:

我有一个看起来像的数据框

Q 1 
1234    data1
1235    data2
1236    data3
Q 2 
1237    data5
1238    data6
1239    data7
1240    data8
Q 3 
1241    data10

在此示例中,Q 值对应于其下方 ID 和数据的一种标头。 我想将所有 Q 值放入一个新列中,将 Q“标题”与相应的 ID 匹配。像这样

Q 1 1234    data1
Q 1 1235    data2
Q 1 1236    data3
Q 2 1237    data5
Q 2 1238    data6
Q 2 1239    data7
Q 2 1240    data8
Q 3 1241    data10

例子

structure(list(V1 = structure(c(9L, 1L, 2L, 3L, 10L, 4L, 5L, 6L, 7L, 11L, 8L), .Label = c("1234", "1235", "1236", "1237","1238", "1239", "1240", "1241", "Q 1", "Q 2", "Q 3"), class = "factor"), 
V2 = structure(c(1L, 2L, 4L, 5L, 1L, 6L, 7L, 8L, 9L, 1L, 3L), .Label = c("", "data1", "data10", "data2", "data3","data5", "data6", "data7", "data8"), class = "factor")), class = "data.frame", row.names = c(NA,-11L))  

【问题讨论】:

    标签: r dataframe


    【解决方案1】:
    subset(transform(d, Id = d$V1[which(d$V2 == "")[cumsum(d$V2 == "")]]), V2 != "")
    #     V1     V2  Id
    #2  1234  data1 Q 1
    #3  1235  data2 Q 1
    #4  1236  data3 Q 1
    #6  1237  data5 Q 2
    #7  1238  data6 Q 2
    #8  1239  data7 Q 2
    #9  1240  data8 Q 2
    #11 1241 data10 Q 3
    

    【讨论】:

      【解决方案2】:

      我们可以创建一个新列 (V3),在其中复制来自 V1 的值,并为不以 "Q" 开头的值创建 NA。我们将那些NAs 替换为tidyr::fill,并从数据中删除V1"Q" 开头的行。

      library(dplyr)
      
      df %>%
        mutate_all(as.character) %>%
        mutate(V3 = replace(V1, !startsWith(V1, "Q"), NA)) %>%
        tidyr::fill(V3) %>%
        filter(!startsWith(V1, "Q"))
      
      #    V1     V2  V3
      #1 1234  data1 Q 1
      #2 1235  data2 Q 1
      #3 1236  data3 Q 1
      #4 1237  data5 Q 2
      #5 1238  data6 Q 2
      #6 1239  data7 Q 2
      #7 1240  data8 Q 2
      #8 1241 data10 Q 3
      

      正如@camille 提到的,我们也可以从V1 中提取"Q \\d",然后使用fill

      df %>%
        mutate(V3 = stringr::str_extract(V1, "Q \\d")) %>%
        tidyr::fill(V3) %>%
        filter(!grepl("^Q", V1))
      

      【讨论】:

      • 如果您只使用正则表达式来提取"Q \\d" 字符串,第二个 mutate 调用可能会更直接,因为您会在不发生这种情况的地方得到 NA。也可能让你跳过第一个变异
      【解决方案3】:

      您可以使用rlerepcbind 标头到数据行。

      i  <- x$V2 == ""
      #i <- grepl("^Q", x$V1) #Alternative
      cbind(header=rep(x$V1[i], rle(i)$lengths[c(FALSE,TRUE)]), x[!i,])
      #   header   V1     V2
      #2     Q 1 1234  data1
      #3     Q 1 1235  data2
      #4     Q 1 1236  data3
      #6     Q 2 1237  data5
      #7     Q 2 1238  data6
      #8     Q 2 1239  data7
      #9     Q 2 1240  data8
      #11    Q 3 1241 data10
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-16
        • 2020-10-21
        • 2021-12-10
        • 1970-01-01
        • 2023-01-13
        • 1970-01-01
        • 2023-03-27
        相关资源
        最近更新 更多