我的标题:
df1 <- tibble(a = c("123*", "123", "124", "678*", "678", "679", "677"))
# A tibble: 7 x 1
a
<chr>
1 123*
2 123
3 124
4 678*
5 678
6 679
7 677
它应该成为什么:
# A tibble: 3 x 2
a b
<chr> <chr>
1 123 124
2 678 679
3 678 677
带星号的值引用下面不带星号的值,直到出现一个带星号的新值,以此类推。
每个带星号的值应该放在第一列,其他值(除了那些与带星号的值相同的值,除了星号)应该放在第二列。如果一个带星号的值后面跟着几个值,它们仍然应该相互链接,所以第一列中的值是重复的,以保持连接。
我知道如何过滤并在每列中带来值,但不确定如何保持连接。
对
我们可以使用tidyverse
。根据*
在'a'中的出现情况创建分组列,用parse_number
提取数字部分,得到distinct
行,按'grp'分组,用'b'的first
值创建新列
library(dplyr)
library(stringr)
df1 %>%
transmute(grp = cumsum(str_detect(a, fixed("*"))),
b = readr::parse_number(a)) %>%
distinct(b, .keep_all = TRUE) %>%
group_by(grp) %>%
mutate(a = first(b)) %>%
slice(-1) %>%
ungroup %>%
select(a, b)
与产出
# A tibble: 3 × 2
a b
<dbl> <dbl>
1 123 124
2 678 679
3 678 677
这是一个基本R选项-
- 使用
cumsum
和grepl
对*
发生的数据进行分割。 - 在每一组中,我们把值类似于恒星值和两列创建一个dataframe。
- 最后,将数据帧列表合并为一个合并的数据帧。
result <- do.call(rbind, lapply(split(df1,
cumsum(grepl('*', df1$a, fixed = TRUE))), function(x) {
a <- x[[1]]
a[1] <- sub('*', '', a[1], fixed = TRUE)
data.frame(a = a[1], b = a[a != a[1]])
}))
rownames(result) <- NULL
result
# a b
#1 123 124
#2 678 679
#3 678 677