【发布时间】:2021-03-06 07:29:13
【问题描述】:
我的数据由多个“块”列组成。在每个块中,列名称相同但由前缀区分:A_color、B_color、C_color、XX_height、YY_height、ZZ_height 等。有时,可能只有词干没有任何前缀的名称。此外,在每个块中只有一列包含数据,其他列是 NA:
######### CHUNK OF COLOR ######## ## ###### CHUNK OF HEIGHT #############
## A_color B_color C_color color ## XX_height height YY_height ZZ_height
## <lgl> <lgl> <dbl> <lgl> ## <lgl> <lgl> <lgl> <dbl>
## 1 NA NA 1 NA ## NA NA NA 15
因此,我想合并块以获得:
## color height
## <dbl> <dbl>
## 1 1 15
示例
我构建了一个哑函数来模拟数据的结构。它的内部无关紧要,只是输出。
library(stringi)
library(dplyr)
library(purrr)
generate_data <-
function(n_of_chunks, n_variants_in_each_chunk, nrows) {
# helper func for later
interweave_vecs <- function(x, y, n){
c(x, y)[order(c(ceiling(seq_along(x) / n), seq_along(y)))]}
# generate col names
names_core <- stri_rand_strings(n = n_of_chunks, length = 10)
names_expanded <- rep(names_core, each = n_variants_in_each_chunk)
prefixes <- replicate(expr = stri_rand_strings(n = 1, length = sample(1:3, 1)), n = length(names_expanded))
names_with_prefixes <- paste(prefixes, names_expanded, sep = "__")
names_final <- interweave_vecs(names_with_prefixes, names_core, n_variants_in_each_chunk)
# generate data
dat <-
rerun(
replicate(expr = sample(c(rep(NA, n_variants_in_each_chunk), runif(1))), n = n_of_chunks) %>%
as.vector() %>%
setNames(., names_final) %>%
bind_rows(),
.n = nrows
) %>%
bind_rows() %>%
cbind(., col_blah = rnorm(nrows), col_foo = letters[1:nrows])
# shuffle columns
dat[,sample(ncol(dat))] %>%
as_tibble()
}
现在模拟数据:
set.seed(2021)
my_df <- generate_data(n_of_chunks = 3, n_variants_in_each_chunk = 3, nrows = 10)
> my_df
## # A tibble: 10 x 14
## v__RmiNdhdGoy s13__1pbZoFVrxX Qx8__1pbZoFVrxX RmiNdhdGoy col_blah Xe__8xOGZuvswo `8xOGZuvswo` A__1pbZoFVrxX w__RmiNdhdGoy col_foo WM__8xOGZuvswo `1pbZoFVrxX` SNr__8xOGZuvswo tYD__RmiNdhdGoy
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 NA NA NA NA -1.50 NA NA 0.846 0.763 a NA NA 0.0479 NA
## 2 0.0729 NA NA NA 2.20 0.365 NA NA NA b NA 0.995 NA NA
## 3 NA NA NA 0.398 0.939 NA NA NA NA c 0.695 0.234 NA NA
## 4 NA 0.541 NA NA 0.713 NA NA NA 0.235 d NA NA 0.470 NA
## 5 NA 0.317 NA NA -0.805 NA 0.163 NA NA e NA NA NA 0.506
## 6 NA NA 0.991 0.0519 0.791 NA 0.888 NA NA f NA NA NA NA
## 7 0.159 NA NA NA 0.116 NA NA 0.223 NA g NA NA 0.260 NA
## 8 0.442 0.0561 NA NA -1.33 NA NA NA NA h 0.663 NA NA NA
## 9 NA NA 0.346 0.479 -1.82 NA 0.193 NA NA i NA NA NA NA
## 10 NA NA 0.443 0.469 -0.403 NA NA NA NA j NA NA 0.450 NA
在my_df 中,列围绕 3 个“词干”进行组织:
- RmiNdhdGoy
- 1pbZoFVrxX
- 8xOGZuvswo
每个版本都有 3 个前缀版本,一个版本只是词干,例如,RmiNdhdGoy 块:
my_df %>%
select(ends_with("RmiNdhdGoy"))
## # A tibble: 10 x 4
## v__RmiNdhdGoy RmiNdhdGoy w__RmiNdhdGoy tYD__RmiNdhdGoy
## <dbl> <dbl> <dbl> <dbl>
## 1 NA NA 0.763 NA
## 2 0.0729 NA NA NA
## 3 NA 0.398 NA NA
## 4 NA NA 0.235 NA
## 5 NA NA NA 0.506
## 6 NA 0.0519 NA NA
## 7 0.159 NA NA NA
## 8 0.442 NA NA NA
## 9 NA 0.479 NA NA
## 10 NA 0.469 NA NA
- 前缀本身是长度在 1-3 个字符之间的字母数字。
- 前缀和词干之间的分隔符是两个下划线 (
__)
我试图想出一种方法来遍历列名,对于那些有两个下划线的,取子字符串 after 那个分隔符,并寻找其他列名以该子字符串结尾,然后将所有这些视为一大块列并将它们合并。
期望的输出
我需要合并每个块以获得:
## # A tibble: 10 x 5
## RmiNdhdGoy `1pbZoFVrxX` `8xOGZuvswo` col_blah col_foo
## <dbl> <dbl> <dbl> <dbl> <chr>
## 1 0.763 0.846 0.0479 -1.50 a
## 2 0.0729 0.995 0.365 2.20 b
## 3 0.398 0.234 0.695 0.939 c
## 4 0.235 0.541 0.470 0.713 d
## 5 0.506 0.317 0.163 -0.805 e
## 6 0.0519 0.991 0.888 0.791 f
## 7 0.159 0.223 0.260 0.116 g
## 8 0.442 0.0561 0.663 -1.33 h
## 9 0.479 0.346 0.193 -1.82 i
## 10 0.469 0.443 0.450 -0.403 j
我看过一堆关于这个主题的 SO 帖子(例如,this 和 this 和 this),但我不明白这些解决方案如何适合我的情况。我希望有人会有一个想法。谢谢!
编辑
在下面@tamtam 的回答之后,我想强调我正在寻找的解决方案是针对generate_data() 的任何 输出,而不是专门针对my_df。我展示了my_df 只是为了说明一个要处理的示例数据。
【问题讨论】: