在 R 中导入数据后更正偏移行

Correct offset rows after importing data in R

问题:出于某种原因,我的软件使用空格来分隔数据,但也在不应算作单独单元格的单词或短语中使用空格,因此使我的数据开始在不规则的柱子上。看起来很简单,我敢肯定其他人已经发布了关于这个特定问题的帖子,但是我找不到合适的术语来清楚地阐明我的问题以找到其他帖子。

示例数据:

bad <- data.frame(c("Block","NA","NA","Block","NA","NA"),
                  c("1:","image2","image3","2:","image5","image6"),
                  c("image1","NA","NA","image4","NA","NA"))

当前输出:

names(bad) <- NULL
print(bad)
1 Block     1: image1
2    NA image2     NA
3    NA image3     NA
4 Block     2: image4
5    NA image5     NA
6    NA image6     NA

期望输出:

1 Block 1: image1
2       NA image2
3       NA image3
4 Block 2: image4
5       NA image5
6       NA image6
7 #From 3 to 2 columns

问题:完成此任务的最有效方法是什么?

我tried/thought关于: 1) 来自data sciencecleanme函数(但它只保留数据行其中有一个 "Block" 字符串并删除其他行); 2) 不确定如何解决这个问题,但基本上使用 gsub 函数替换第 2 列中包含 [1:5] 后跟“:”的每个值和 "Block [1:5]:",然后移动它整行向左(但问题是我也有我不想折叠的日期可能以完全相同的方式开始的行); 3) 即使我使用 gsub 函数将一个字符串替换为另一个字符串,我仍然必须折叠列,我可以使用 paste 函数来完成,但同样,我只想折叠或替换以 "Block" 字符串开头的每一行的前两列——我不确定将所有这些组合起来的语法规范,或者我是否真的只是在无意义地让我的生活复杂化。

注意:我做过教程等等,但是找不到具体的方法。请指点我右边的post/duplicate,如果这个已经存在就删掉。谢谢!

更新

根据我的实际数据结构稍微调整以下 earch 的答案,我找到了一个可行的解决方案(我的数据集比我的示例更复杂)。供参考:

# Continuing from example above
bad <- as.matrix(bad) # Note that I didn't need this step for my actual data but needed here

good <- lapply(1:nrow(bad), function(i) bad[i, !is.na(bad[i, ])]) # Transforms rows into lists

good <- lapply(good, function(x) {
  if (x[1] == "Block") { # If the row starts with the word "Block", then do the following:
    c(paste(x[1:2], collapse = " "), x[3:length(x)]) # Paste the first two cells collapsed together (so Block + the block number belonging to the next cell) while adding the remaining row cells
  } else {
    c(x) # Just put the row in a list (didn't worked without this step)
  }
})

good <- do.call(rbind, good) # Binds elements from list together
good <- as.data.frame(good) # Puts everything nicely in a neat dataframe
good

        V1     V2       V3
1 Block 1: image1 Block 1:
2       NA image2       NA
3       NA image3       NA
4 Block 2: image4 Block 2:
5       NA image5       NA
6       NA image6       NA

大家可以看到,我用这个样本数据集修改还是有点小问题,就是"Block 2:"接下来又重复了一遍,不过问题不大,至少是实际的数据对齐。在我的实际数据中,有更多的列,所以没有发生这种情况,使用这个解决方案,第三列和下一列实际上包含反应时间和其他信息。

下面的呢?我不确定您是否希望 "NA" 成为实际的 NA 或字符串,但您可以将下面的代码修改为两者之一。我也不确定所需的效果是新的 data.frame 有两列,还是在某些情况下它应该更多(或更少)。我假设是前者。

> bad <- data.frame(
+   c("Block","NA","NA","Block","NA","NA"),
+   c("1:","image2","image3","2:","image5","image6"),
+   c("image1","NA","NA","image4","NA","NA")
+ )
> names(bad) <- NULL
> bad

1 Block     1: image1
2    NA image2     NA
3    NA image3     NA
4 Block     2: image4
5    NA image5     NA
6    NA image6     NA
> 
> bad <- as.matrix(bad)
> bad[bad == "NA"] <- NA
> 
> good <- lapply(1:nrow(bad), function(i) bad[i, !is.na(bad[i, ])])
> good <- lapply(good, function(x) {
+   if(length(x) == 1) {
+     c(NA, x)
+   } else {
+     c(paste(x[1:(length(x) - 1)], collapse = " "), x[length(x)])
+   }
+ })
> good <- do.call(rbind, good)
> good <- as.data.frame(good)
> good
        V1     V2
1 Block 1: image1
2     <NA> image2
3     <NA> image3
4 Block 2: image4
5     <NA> image5
6     <NA> image6