[英]Coalescing multiple chunks of columns with the same suffix in names (R)
我有一個數據集,其中包含具有不同前綴但后綴相同的各種“塊”列:
ID | A034 | B034 | C034 | D034 | A099 | B099 | A123 | B123 | ... |
---|---|---|---|---|---|---|---|---|---|
1 | 不適用 | 1 | 不適用 | 不適用 | 不適用 | 3 | 1 | 不適用 | ... |
2 | 2 | 不適用 | 不適用 | 不適用 | 2 | 不適用 | 不適用 | 2 | ... |
3 | 不適用 | 不適用 | 2 | 不適用 | 不適用 | 2 | 1 | 不適用 | ... |
每個“塊”中的列數也各不相同。 有沒有什么方法(除了手動,這是我一直在努力用coalesce(.,! select(., contains("XXX")))
) 來根據共享后綴自動合並塊? 也就是說,結果應該類似於
ID | 034 | 099 | 123 | ... |
---|---|---|---|---|
1 | 1 | 3 | 1 | ... |
2 | 2 | 2 | 2 | ... |
3 | 2 | 2 | 1 | ... |
我不確定如何開始做這樣的事情,所以任何建議都會非常有幫助。
我們使用pivot_longer
將數據重塑為“long”格式,然后按“ID” na.omit
across
NA 元素(我們假設每列只有一個非 NA按組)
library(dplyr)
library(tidyr)
df1 %>%
pivot_longer(cols = -ID, names_to = ".value",
names_pattern = "[A-Z](\\d+)") %>%
group_by(ID) %>%
summarise(across(everything(), na.omit), .groups = 'drop')
-輸出
# A tibble: 3 x 4
ID `034` `099` `123`
<int> <int> <int> <int>
1 1 1 3 1
2 2 2 2 2
3 3 2 2 1
或者為了安全起見,使用complete.cases
為非 NA 元素創建邏輯向量,並提取第一個元素(假設我們只需要一個非 NA - 如果非 NA 長度不同,我們可能需要返回一份list
)
df1 %>%
pivot_longer(cols = -ID, names_to = ".value",
names_pattern = "[A-Z](\\d+)") %>%
group_by(ID) %>%
summarise(across(everything(), ~ .[complete.cases(.)][1]))
df1 <- structure(list(ID = 1:3, A034 = c(NA, 2L, NA), B034 = c(1L, NA,
NA), C034 = c(NA, NA, 2L), D034 = c(NA, NA, NA), A099 = c(NA,
2L, NA), B099 = c(3L, NA, 2L), A123 = c(1L, NA, 1L), B123 = c(NA,
2L, NA)), class = "data.frame", row.names = c(NA, -3L))
另一種方法
library(tidyverse)
split(names(df1)[-1], gsub('^\\D*(\\d+)$', '\\1', names(df1)[-1])) %>% map(~df1[c('ID', .x)]) %>%
imap(~ .x %>% group_by(ID) %>% rowwise %>% transmute(!!.y := first(na.omit(c_across(everything())))) %>% ungroup) %>%
reduce(left_join, by = 'ID')
#> # A tibble: 3 x 4
#> ID `034` `099` `123`
#> <int> <int> <int> <int>
#> 1 1 1 3 1
#> 2 2 2 2 2
#> 3 3 2 2 1
由代表 package (v2.0.0) 於 2021 年 6 月 20 日創建
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.