R- 在特定的字符串/模式之后将行添加到数据框
R- add row to data frame after a specific sting/ pattern
我试图在我的数据框中填充一些缺失的数据,它看起来像:
ID Value
1234 0001A
Text Text 2
1235 0001A
1236 0001A
Text Text 2
1237 0001A
1238 0001A
1239 0001A
Text Text 2
1240 0001A
我想要的是在 ID
中的每个数值之后我想插入一个 Text
行,所以最终结果将是:
ID Value
1234 0001A
Text Text 2
1235 0001A
Text
1236 0001A
Text Text 2
1237 0001A
Text
1238 0001A
Text
1239 0001A
Text Text 2
1240 0001A
Text
我找到了这个答案,并尝试根据我的要求对其进行调整,但并不愉快。
根据 NA 值的存在添加行
例子
df <- structure(list(ID = c("1234", "Text", "1235", "1236", "Text", "1237", "1238", "1239", "Text", "1240"), Value = structure(c(1L,
2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L), .Label = c("0001A", "Text 2"), class = "factor")), row.names = c(NA, -10L), class = "data.frame")
注意:ID 列作为字符元素存在。
稍后我们可以添加行号作为对 arrange
数据的引用。
library(dplyr)
df <- df %>% mutate(row = row_number())
过滤ID
中有数字但后面没有'Text'
的行,将ID
值更改为'Text'
和Value
清空字符串并绑定到原始数据框和 arrange
.
df %>%
filter(grepl('\d+', ID) & lead(ID, default = last(ID)) != 'Text') %>%
mutate(ID = 'Text', Value = '') %>%
bind_rows(df) %>%
arrange(row, desc(Value)) %>%
select(-row)
# ID Value
#1 1234 0001A
#2 Text Text 2
#3 1235 0001A
#4 Text
#5 1236 0001A
#6 Text Text 2
#7 1237 0001A
#8 Text
#9 1238 0001A
#10 Text
#11 1239 0001A
#12 Text Text 2
#13 1240 0001A
#14 Text
您可以使用 grepl
查找有数字的位置,使用 diff
查找插入新行的位置。使用 lapply
如果需要,您可以在每一行插入一个新行 rbind
。
i <- grepl("^[0-9]+$", df$ID)
j <- c(diff(i) == 0, i[length(i)])
do.call(rbind, lapply(1:nrow(df), function(x) rbind(df[x,]
, data.frame(ID="Text", Value="")[j[x]])))
# ID Value
#1 1234 0001A
#2 Text Text 2
#3 1235 0001A
#11 Text
#4 1236 0001A
#5 Text Text 2
#6 1237 0001A
#12 Text
#7 1238 0001A
#13 Text
#8 1239 0001A
#9 Text Text 2
#10 1240 0001A
#14 Text
我试图在我的数据框中填充一些缺失的数据,它看起来像:
ID Value
1234 0001A
Text Text 2
1235 0001A
1236 0001A
Text Text 2
1237 0001A
1238 0001A
1239 0001A
Text Text 2
1240 0001A
我想要的是在 ID
中的每个数值之后我想插入一个 Text
行,所以最终结果将是:
ID Value
1234 0001A
Text Text 2
1235 0001A
Text
1236 0001A
Text Text 2
1237 0001A
Text
1238 0001A
Text
1239 0001A
Text Text 2
1240 0001A
Text
我找到了这个答案,并尝试根据我的要求对其进行调整,但并不愉快。
例子
df <- structure(list(ID = c("1234", "Text", "1235", "1236", "Text", "1237", "1238", "1239", "Text", "1240"), Value = structure(c(1L,
2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L), .Label = c("0001A", "Text 2"), class = "factor")), row.names = c(NA, -10L), class = "data.frame")
注意:ID 列作为字符元素存在。
稍后我们可以添加行号作为对 arrange
数据的引用。
library(dplyr)
df <- df %>% mutate(row = row_number())
过滤ID
中有数字但后面没有'Text'
的行,将ID
值更改为'Text'
和Value
清空字符串并绑定到原始数据框和 arrange
.
df %>%
filter(grepl('\d+', ID) & lead(ID, default = last(ID)) != 'Text') %>%
mutate(ID = 'Text', Value = '') %>%
bind_rows(df) %>%
arrange(row, desc(Value)) %>%
select(-row)
# ID Value
#1 1234 0001A
#2 Text Text 2
#3 1235 0001A
#4 Text
#5 1236 0001A
#6 Text Text 2
#7 1237 0001A
#8 Text
#9 1238 0001A
#10 Text
#11 1239 0001A
#12 Text Text 2
#13 1240 0001A
#14 Text
您可以使用 grepl
查找有数字的位置,使用 diff
查找插入新行的位置。使用 lapply
如果需要,您可以在每一行插入一个新行 rbind
。
i <- grepl("^[0-9]+$", df$ID)
j <- c(diff(i) == 0, i[length(i)])
do.call(rbind, lapply(1:nrow(df), function(x) rbind(df[x,]
, data.frame(ID="Text", Value="")[j[x]])))
# ID Value
#1 1234 0001A
#2 Text Text 2
#3 1235 0001A
#11 Text
#4 1236 0001A
#5 Text Text 2
#6 1237 0001A
#12 Text
#7 1238 0001A
#13 Text
#8 1239 0001A
#9 Text Text 2
#10 1240 0001A
#14 Text