在 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 science的cleanme
函数(但它只保留数据行其中有一个 "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
问题:出于某种原因,我的软件使用空格来分隔数据,但也在不应算作单独单元格的单词或短语中使用空格,因此使我的数据开始在不规则的柱子上。看起来很简单,我敢肯定其他人已经发布了关于这个特定问题的帖子,但是我找不到合适的术语来清楚地阐明我的问题以找到其他帖子。
示例数据:
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 science的cleanme
函数(但它只保留数据行其中有一个 "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