我有一个数据帧,其中有特定的行出错,这意味着两行被合并为一行,用空格表示。我有错误所在行的索引,我希望使用索引构建一个函数,简单地创建两个新列表,然后我可以将它们插入数据帧(作为2行(并替换不正确的行。
我在R中有以下数据帧(第3行为错误(:
Location V1 V2 V3 V4
1 nyc 2 20 9 2
2 bos 4 5 3 8
3 atl m dal 1 4 3 4 1 3 5 2
4 mia 3 1 8 4
structure(list(Location = c("nyc", "bos", "atl m dal", "mia"),
V1 = c("2", "4", "1 4", "3"), V2 = c("20", "5", "3 4", "1"
), V3 = c("9", "3", "1 3", "8"), V4 = c("2", "8", "5 2",
"4")), row.names = c(NA, 4L), class = "data.frame")
步骤1:所需的输出将是两个列表/矢量(对于每个错误行(,如下所示:
atl m
1
3
1
5
dal
4
4
3
2
步骤2:一旦我有了这些列表,我应该能够将它们作为行插入/添加到现有的数据帧中(并删除错误行(,例如:
Location V1 V2 V3 V4
1 nyc 2 20 9 2
2 bos 4 5 3 8
3 atl m 1 3 1 5
4 dal 4 4 3 2
5 mia 3 1 8 4
主要是希望在步骤1中获得帮助。除第一列外,所有列(V1…V4(都有一个空白,可以用作分隔符来拆分每个值,这很容易,但第一列的位置并没有那么简单。我需要根据我可以匹配的另一个列表手动为该列的字符串子集。
我们可以识别有错误的行,这些行中有空白(\s
(。为这些行创建一个单独的数据帧。获取location
并不是一件简单的事情,因为它们中有很多空白。我使用的逻辑是最后一个单词进入新行,而之前的所有单词都留在同一行。
最后,我们将这两个数据帧组合起来,得到一个完整的数据帧。
library(dplyr)
inds <- grep('\s', df$V1)
tmp <- df[inds, ]
tmp %>%
tidyr::separate_rows(everything(), sep = '(\s)(?!.*\s)') %>%
bind_rows(df[-inds, ]) %>%
type.convert(as.is = TRUE)
# Location V1 V2 V3 V4
# <chr> <int> <int> <int> <int>
#1 atl m 1 3 1 5
#2 dal 4 4 3 2
#3 nyc 2 20 9 2
#4 bos 4 5 3 8
#5 mia 3 1 8 4
这有点粗糙,但您可以直接复制问题行,并获取"quot;分割为第一行("atlm"(;dal";行:
tibble(df) %>%
mutate(across(.fns = ~str_replace(., " \w+$", ""))) %>%
add_row(
df %>%
slice(3) %>%
mutate(across(.fns = ~str_replace(., "^.* (\w+)$", "\1")))
)
# A tibble: 5 x 5
Location V1 V2 V3 V4
<chr> <chr> <chr> <chr> <chr>
1 nyc 2 20 9 2
2 bos 4 5 3 8
3 atl m 1 3 1 5
4 mia 3 1 8 4
5 dal 4 4 3 2