用条件分隔行
Separate rows with conditions
我有这个数据框 separate_on_condition
有两列:
separate_on_condition <- data.frame(first = 'a3,b1,c2', second = '1,2,3,4,5,6')`
# first second
# 1 a3,b1,c2 1,2,3,4,5,6
我怎样才能把它变成:
# A tibble: 6 x 2
first second
<chr> <chr>
1 a 1
2 a 2
3 a 3
4 b 4
5 c 5
6 c 6
其中:
a3
将分成 3 行
b1
成 1 行
c2
分成 2 行
有没有比在 first
列上使用 rep()
和在 second
列上使用 separate_rows()
更好的方法?
如有任何帮助,我们将不胜感激!
您可以选择以下基础 R 选项
with(
separate_on_condition,
data.frame(
first = unlist(sapply(
unlist(strsplit(first, ",")),
function(x) rep(gsub("\d", "", x), as.numeric(gsub("\D", "", x)))
), use.names = FALSE),
second = eval(str2lang(sprintf("c(%s)", second)))
)
)
这给出了
first second
1 a 1
2 a 2
3 a 3
4 b 4
5 c 5
6 c 6
- 创建行号列以说明多行。
- 在单独的行中拆分
,
上的 second
列。
- 为每一行提取要重复的数据以及需要重复的次数。
library(dplyr)
library(tidyr)
library(stringr)
separate_on_condition %>%
mutate(row = row_number()) %>%
separate_rows(second, sep = ',') %>%
group_by(row) %>%
mutate(first = rep(str_extract_all(first(first), '[a-zA-Z]+')[[1]],
str_extract_all(first(first), '\d+')[[1]])) %>%
ungroup %>%
select(-row)
# first second
# <chr> <chr>
#1 a 1
#2 a 2
#3 a 3
#4 b 4
#5 c 5
#6 c 6
这是另一种方法:
- 将
NA
添加到 first
以获得相同的 length
- 使用
separate_rows
将每个元素排成一行
- 使用正则表达式数字
extract
将 first
拆分为 first
和 helper
- 分组和
slice
按 helper
中的值
- 做一些调整
library(tidyr)
library(dplyr)
separate_on_condition %>%
mutate(first = str_c(first, ",NA,NA,NA")) %>%
separate_rows(first, second, sep = "[^[:alnum:].]+", convert = TRUE) %>%
extract(first, into = c("first", "helper"), "(.{1})(.{1})", remove=FALSE) %>%
group_by(second) %>%
slice(rep(1:n(), each = helper)) %>%
ungroup() %>%
drop_na() %>%
mutate(second = row_number()) %>%
select(first, second)
first second
<chr> <int>
1 a 1
2 a 2
3 a 3
4 b 4
5 c 5
6 c 6
我有这个数据框 separate_on_condition
有两列:
separate_on_condition <- data.frame(first = 'a3,b1,c2', second = '1,2,3,4,5,6')`
# first second
# 1 a3,b1,c2 1,2,3,4,5,6
我怎样才能把它变成:
# A tibble: 6 x 2
first second
<chr> <chr>
1 a 1
2 a 2
3 a 3
4 b 4
5 c 5
6 c 6
其中:
a3
将分成 3 行b1
成 1 行c2
分成 2 行
有没有比在 first
列上使用 rep()
和在 second
列上使用 separate_rows()
更好的方法?
如有任何帮助,我们将不胜感激!
您可以选择以下基础 R 选项
with(
separate_on_condition,
data.frame(
first = unlist(sapply(
unlist(strsplit(first, ",")),
function(x) rep(gsub("\d", "", x), as.numeric(gsub("\D", "", x)))
), use.names = FALSE),
second = eval(str2lang(sprintf("c(%s)", second)))
)
)
这给出了
first second
1 a 1
2 a 2
3 a 3
4 b 4
5 c 5
6 c 6
- 创建行号列以说明多行。
- 在单独的行中拆分
,
上的second
列。 - 为每一行提取要重复的数据以及需要重复的次数。
library(dplyr)
library(tidyr)
library(stringr)
separate_on_condition %>%
mutate(row = row_number()) %>%
separate_rows(second, sep = ',') %>%
group_by(row) %>%
mutate(first = rep(str_extract_all(first(first), '[a-zA-Z]+')[[1]],
str_extract_all(first(first), '\d+')[[1]])) %>%
ungroup %>%
select(-row)
# first second
# <chr> <chr>
#1 a 1
#2 a 2
#3 a 3
#4 b 4
#5 c 5
#6 c 6
这是另一种方法:
- 将
NA
添加到first
以获得相同的length
- 使用
separate_rows
将每个元素排成一行 - 使用正则表达式数字
extract
将first
拆分为first
和helper
- 分组和
slice
按helper
中的值
- 做一些调整
library(tidyr)
library(dplyr)
separate_on_condition %>%
mutate(first = str_c(first, ",NA,NA,NA")) %>%
separate_rows(first, second, sep = "[^[:alnum:].]+", convert = TRUE) %>%
extract(first, into = c("first", "helper"), "(.{1})(.{1})", remove=FALSE) %>%
group_by(second) %>%
slice(rep(1:n(), each = helper)) %>%
ungroup() %>%
drop_na() %>%
mutate(second = row_number()) %>%
select(first, second)
first second
<chr> <int>
1 a 1
2 a 2
3 a 3
4 b 4
5 c 5
6 c 6