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

在R中导入数据后更正偏移行,r,dataframe,formatting,data-cleaning,data-import,R,Dataframe,Formatting,Data Cleaning,Data Import,问题:出于某种原因,我的软件使用空格分隔数据,但在单词或短语中也使用空格,这些空格不应算作单独的单元格,因此使我的数据从不规则的列开始。这看起来很简单,我相信其他人也在发布这个问题,但我找不到合适的术语来清楚地表达我的问题,以便找到其他帖子 示例数据: bad <- data.frame(c("Block","NA","NA","Block","NA","NA"), c("1:","image2","image3","2:","image5","imag

问题:出于某种原因,我的软件使用空格分隔数据,但在单词或短语中也使用空格,这些空格不应算作单独的单元格,因此使我的数据从不规则的列开始。这看起来很简单,我相信其他人也在发布这个问题,但我找不到合适的术语来清楚地表达我的问题,以便找到其他帖子

示例数据:

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
问题:最有效的方法是什么

我尝试/思考的内容:1)来自的
cleanme
函数(但它只保留有“块”字符串的数据行,并删除其他行);2) 不确定如何进行此操作,但基本上使用
gsub
函数将包含[1:5]的第2列的每个值替换为“:”和“Block[1:5]:”,然后将整行移到左侧(但问题是,我也有一些日期行,我不希望以完全相同的方式折叠);3) 即使我使用
gsub
函数将一个字符串替换为另一个字符串,我仍然需要折叠列,这可以通过
paste
函数来完成,但同样,我只想折叠或替换以“Block”开头的每行的前两列字符串和我不确定的语法规范,以结合所有这些,或是否我真的只是复杂化我的生活没有任何意义

注意:我已经完成了教程等,但我找不到具体的方法来完成。请让我参考正确的帖子/副本,如果已经存在,请删除此帖子/副本。谢谢

使现代化 稍微将下面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
#从上面的示例继续

坏以下情况如何?我不确定您希望“NA”是实际的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
>坏名字(坏)坏名字
1块1:图像1
2 NA图像2 NA
3 NA图像3 NA
4块2:图像4
5 NA图像5 NA
6 NA图像6 NA
> 
>坏坏坏[坏==“NA”]
>好,好,好
V1 V2
1块1:图像1
2图像2
3图3
4块2:图像4
5图5
6图像6

谢谢@earch!您的代码对我的示例非常有效!你还说得对,我实际上想要的是真正的NAs而不是字符串(我的错!)。它对我的实际数据不太管用,因为我低估了数据的混乱程度会有多大问题,但我能够针对我的情况稍微编辑代码(正如您所提到的,这里有更多的列,长度不等)。另外,我错了,这些不是真正的NAs,只是空字符串(“”),但我最终不必去碰它。我将发布最终解决方案,作为对原始帖子的编辑。