【问题标题】:Merge Alternating Rows合并交替行
【发布时间】:2020-11-06 14:04:16
【问题描述】:

我从 pdf 中提取数据并遇到了一个小问题。一些单元格被分隔成两行,以便数据在某些单元格中具有 NA,而在其他单元格中具有值。这些值我想简单地合并到上面的单元格中

有趣的是,我要合并其他行的每条“真实”行都以相同的符号开头,即“§”。

我有大约 1000 个观察结果,所以自动化解决方案会很棒

first <- c("§", "3", "4")
second <- c(NA, "2", NA)
third <- c("§", "2", 5)
fourth <- c(NA, "2", "3")
... and so on

df <- as.data.frame(rbind(first, second, third, fourth))

expected output: 
first_e <- c("§", "32", "4")
second_e <- c "§", "22", "53")

df_e <- as.data.frame(rbind(first_e, second_e))

如果有人有想法,那就太棒了(:

柏林最佳

【问题讨论】:

  • 你能分享你的预期输出吗?
  • 如果我理解正确的话,并不总是有第二行 - 因此很难区分什么定义了“第二行”和什么是“第一行”。这意味着您必须确定,“第二”行总是至少有一个 NA,而“第一”行永远不会有任何 NA。这将是“自动化”的最低假设
  • 嗨,总是有第二行 - 但是,有些是空的,有些是有值的。
  • 预期输出:``` 输出
  • 另一种可能性是所有“实际”行都以相同的符号开头,即“§”。我编辑了示例

标签: r dataframe rows


【解决方案1】:

考虑使用ifelse + cumsum 标记§ 列,以使用pasteaggregate 生成分组字段:

# BUILD DATA FRAME
df <- setNames(rbind.data.frame(first, second, third, fourth, stringsAsFactors=FALSE),
               c("col1", "col2", "col3"))

# CONVERT ALL NAs TO EMPTY STRING
df[is.na(df)] <- ""

# GENERATE GROUPING COLUMN
df$section <- cumsum(ifelse(df$col1 == "§", 1, 0))
df
#   col1 col2 col3 section
# 1    §    3    4       1
# 2         2            1
# 3    §    2    5       2
# 4         2    3       2

# AGGREGATE BY GROUPING COLUMNS
clean_df <- aggregate(. ~ section, df, paste, collapse="")[-1]
clean_df
#   col1 col2 col3
# 1    §   32    4
# 2    §   22   53

Online Demo

【讨论】:

  • 这看起来是一个非常有趣的方法,将在星期一检查一下!非常感谢!
【解决方案2】:

只需将列的奇数元素与偶数元素粘贴:

# vectors of TRUEs in odd or even positions
odd <- rep(c(T,F), length.out=nrow(df))
evn <- rep(c(F,T), length.out=nrow(df))

# for each column...
result <- lapply(df, function(col) {
    paste0(ifelse(is.na(col[odd]), '', col[odd]),
           ifelse(is.na(col[evn]), '', col[evn]))  
})
as.data.frame(result)

【讨论】:

    【解决方案3】:

    如果总是有第二行,一个可能的解决方案是:

    library(dplyr)
    

    库(dplyr)

    df %>% 
      # use the row number as colum
      dplyr::mutate(ID = dplyr::row_number()) %>% 
      # substract 1 from very even row numer to build groups
      dplyr::mutate(ID = ifelse(ID %% 2 == 0, ID - 1, ID)) %>% 
      # group by the new ID
      dplyr::group_by(ID) %>% 
      # convert all NAs to "" (empty string)
      dplyr::mutate_all(~ ifelse(is.na(.), "", .)) %>% 
      # concatenate all strings per group
      dplyr::mutate_all( ~ paste(., collapse = "")) %>% 
      # select only distinct cases (do elimitate "seconds" as the now are identical to "frists)
      dplyr::distinct()
    
    
      V1    V2    V3       ID
      <chr> <chr> <chr> <dbl>
    1 4     32    4         1
    

    我在结果中留下了创建的 ID 号,但如果您愿意,您可以在计算后删除/删除它

    【讨论】:

    • 我想 POSIXct 只出现在第一行,所以他们的第二行是 NA:如果是这样,您可以在操作之前将 POSIXct 列转换/变异为字符,然后在病房后将其转换/变异回来 -因为您将添加“注意”,这应该可以解决问题
    • 嘿,结果非常好,非常感谢! ((::
    • 嘿 ja,没有删除之前的评论故意 - 转换为 char 作品
    • @lupo404 请接受我的正确回答,以便其他人知道这已解决! stackoverflow.com/help/someone-answers
    猜你喜欢
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 2019-07-22
    • 1970-01-01
    • 1970-01-01
    • 2018-05-25
    相关资源
    最近更新 更多