在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,只是空字符串(“”),但我最终不必去碰它。我将发布最终解决方案,作为对原始帖子的编辑。