数据帧df
的数值向量id0
的每个不同值都有一行,但id0
单元格中的尾随零表示必须沿其转换文件的重要组。以下是df
:的12个观察结果
row id0 id0_ntz
a 111000 3
b 111010 1
c 112345 0
d 111974 0
e 112090 1
f 114000 3
g 114099 0
h 555001 0
i 555012 0
j 461000 3
k 461020 1
l 111090 0
让我们将具有三个尾随零的id0
的每个值(即其中id0_ntz == 3
(称为"0">大id";并且每一个不符合该模式的值都是"a">小id"上面的12个obs包括三个大id(row
值a
、f
和j
(。对于每个大id,我需要:
- 查找与ith大id的前三位匹配的
id0
的其他值 - 将每个匹配的
id0
的值添加到一个称为idj
的j离散向量中,其中j-是一个从1到j的后缀,它有效地计算嵌套在i-th大id中的匹配小id
如果df
只包括上面显示的12行,则正确的结果如下所示:
row id0 id0_ntz id1 id2 id3
a 111000 3 111010 111974 111090
b 111010 1 NA NA NA
c 112345 0 NA NA NA
d 111974 0 NA NA NA
e 112090 1 NA NA NA
f 114000 3 114099 NA NA
g 114099 0 NA NA NA
h 555001 0 NA NA NA
i 555012 0 NA NA NA
j 461000 3 461020 NA NA
k 461020 1 NA NA NA
l 111090 0 NA NA NA
我对任何动态解决此问题的解决方案持开放态度(即,对大id、 小id附言:我需要再次做同样的事情,先是id0_ntz == 2
,然后是1
,但这个发布的问题的可接受答案只需要解决id0_ntz == 3
的问题。
这将达到您的目的
df <- read.table(text = 'row id0 id0_ntz
a 111000 3
b 111010 1
c 112345 0
d 111974 0
e 112090 1
f 114000 3
g 114099 0
h 555001 0
i 555012 0
j 461000 3
k 461020 1
l 111090 0', header = T)
df$id0 <- as.character(df$id0)
library(tidyverse)
df %>%
filter(id0_ntz == 3) %>%
mutate(big_id = substr(id0, 1, 3)) -> big_id
df %>% mutate(id0 = as.character(id0)) %>%
left_join(df %>% mutate(id = as.character(id0),
dummy = match(substr(id, 1, 3), big_id$big_id)) %>%
filter(!is.na(dummy)) %>%
group_by(dummy) %>%
mutate(d2 = paste0('id', row_number() - 1)) %>% select(-id0) %>%
pivot_wider(id_cols = dummy, names_from = d2, values_from = id),
by = c('id0')) %>%
select(-dummy)
#> row id0 id0_ntz id1 id2 id3
#> 1 a 111000 3 111010 111974 111090
#> 2 b 111010 1 <NA> <NA> <NA>
#> 3 c 112345 0 <NA> <NA> <NA>
#> 4 d 111974 0 <NA> <NA> <NA>
#> 5 e 112090 1 <NA> <NA> <NA>
#> 6 f 114000 3 114099 <NA> <NA>
#> 7 g 114099 0 <NA> <NA> <NA>
#> 8 h 555001 0 <NA> <NA> <NA>
#> 9 i 555012 0 <NA> <NA> <NA>
#> 10 j 461000 3 461020 <NA> <NA>
#> 11 k 461020 1 <NA> <NA> <NA>
#> 12 l 111090 0 <NA> <NA> <NA>
创建于2021-05-28由reprex包(v2.0.0(
我会使用下面的方法。它很短。
library(tidyverse)
df %>%
group_by(big_id = substr(id0, 1, 3)) %>%
mutate(id = ifelse(substr(id0, 4, 6) == "000",
list(setdiff(unique(id0),
paste0(big_id, "000"))),
list())) %>%
unnest_wider(col = id,
names_sep = "")
#> # A tibble: 12 x 7
#> # Groups: big_id [5]
#> row id0 id0_ntz big_id id1 id2 id3
#> <chr> <int> <int> <chr> <int> <int> <int>
#> 1 a 111000 3 111 111010 111974 111090
#> 2 b 111010 1 111 NA NA NA
#> 3 c 112345 0 112 NA NA NA
#> 4 d 111974 0 111 NA NA NA
#> 5 e 112090 1 112 NA NA NA
#> 6 f 114000 3 114 114099 NA NA
#> 7 g 114099 0 114 NA NA NA
#> 8 h 555001 0 555 NA NA NA
#> 9 i 555012 0 555 NA NA NA
#> 10 j 461000 3 461 461020 NA NA
#> 11 k 461020 1 461 NA NA NA
#> 12 l 111090 0 111 NA NA NA
由reprex包(v0.3.0(于2021-05-27创建
library(tidyverse)
df <- read.table(text = 'row id0 id0_ntz
a 111000 3
b 111010 1
c 112345 0
d 111974 0
e 112090 1
f 114000 3
g 114099 0
h 555001 0
i 555012 0
j 461000 3
k 461020 1
l 111090 0', header = T)
df %>%
mutate(id = id0 %/% 1000 * 1000) %>%
group_by(id) %>%
mutate(row_id = row_number() - 1) %>%
ungroup() %>%
filter(row_id != 0) %>%
pivot_wider(id, names_from = row_id, values_from = id0, names_prefix = "id") %>%
right_join(df, by = c("id" = "id0")) %>%
rename(id0 = id) %>%
arrange(row)
#> # A tibble: 12 x 6
#> id0 id1 id2 id3 row id0_ntz
#> <dbl> <int> <int> <int> <chr> <int>
#> 1 111000 111010 111974 111090 a 3
#> 2 111010 NA NA NA b 1
#> 3 112345 NA NA NA c 0
#> 4 111974 NA NA NA d 0
#> 5 112090 NA NA NA e 1
#> 6 114000 114099 NA NA f 3
#> 7 114099 NA NA NA g 0
#> 8 555001 NA NA NA h 0
#> 9 555012 NA NA NA i 0
#> 10 461000 461020 NA NA j 3
#> 11 461020 NA NA NA k 1
#> 12 111090 NA NA NA l 0
创建于2021-05-27由reprex包(v2.0.0(