添加标识符适合多种模式的列
Add columns where identifiers fit multiple patterns
数据框 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_ntz == 3
处)调用 id0
的每个值一个“big id”,每个值不不适合这个模式“little id。”上面的12个obs包括三个大id(row
值a
、f
和j
)。对于每个 big id,我需要:
- 查找
id0
的所有其他值,这些值与第 i 个 的 前三位数字 相匹配大id
- 将每个匹配项的
id0
的值添加到称为 idj
的 j 个离散向量之一,其中 j 是一个范围从 1 到 j 的后缀,它有效地统计了嵌套在 i[= 中的匹配 little ids 的数量62=第大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[=58= 的数量无关],以及生成的 idj
个向量)。
P.S.: 我需要在 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>
由 reprex package (v2.0.0)
于 2021-05-28 创建
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
由 reprex package (v2.0.0)
于 2021-05-27 创建
我会使用下面的方法。很短。
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 package (v0.3.0)
于 2021-05-27 创建
数据框 df
的数值向量 id0
的每个不同值都有一行 - 但 id0
的单元格中的尾随零表示文件必须沿用的重要组被改造。这是 df
:
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_ntz == 3
处)调用 id0
的每个值一个“big id”,每个值不不适合这个模式“little id。”上面的12个obs包括三个大id(row
值a
、f
和j
)。对于每个 big id,我需要:
- 查找
id0
的所有其他值,这些值与第 i 个 的 前三位数字 相匹配大id - 将每个匹配项的
id0
的值添加到称为idj
的 j 个离散向量之一,其中 j 是一个范围从 1 到 j 的后缀,它有效地统计了嵌套在 i[= 中的匹配 little ids 的数量62=第大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[=58= 的数量无关],以及生成的 idj
个向量)。
P.S.: 我需要在 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>
由 reprex package (v2.0.0)
于 2021-05-28 创建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
由 reprex package (v2.0.0)
于 2021-05-27 创建我会使用下面的方法。很短。
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 package (v0.3.0)
于 2021-05-27 创建