R语言 从数据表中分离变量并创建新的数据表

kzipqqlq  于 2023-03-20  发布在  其他
关注(0)|答案(3)|浏览(176)

我要转换此表(Csp_raw
| CSp|注|
| - ------|- ------|
| 十二至十三页|小行星4167|
| 第十二至十三页、第一二八至一二九页|五个|
| 第12至13页、第128至129页、第73至74页|六个|
| 第十二至十三页、第四十一至四十二页|三个|
| 第12至13页、第41至42页、第128至129页、第73至74页|第二章|
| 第12至13页、第41至42页、第73至74页|四个|
| 第十二至十三页、第七十三至七十四页|二百五十五|
| 第128页至第129页|十八|
| 第128页至第129页、第73页至第74页|二十三|
| 第四十一至四十二页|五十八|
| 第四十一至四十二页、第一二八至一二九页|1个|
| 第41至42页、第128至129页、第73至74页|十二|
| 第四十一至四十二页、第七十三至七十四页|二十六|
| 小六至小七|1个|
| 第七十三至七十四页|六零八|
导入此表(Csp_table):
| 十二至十三页|第128页至第129页|第七十三至七十四页|第四十一至四十二页|小六至小七|
| - ------|- ------|- ------|- ------|- ------|
| 小行星41946|六十七|九三六|一百零六|1个|
我使用这个代码:

tmp_colname <- str_c(CSp_raw$CSp, collapse = ',') %>% 
  str_split(pattern = ',')

CSp_table <- lapply(tmp_colname, function(p){
  list(data.frame(p[1], p[2], p[3], p[4], p[5]))
})

CSp_table <- data.frame(CSp_table) %>% 
  rename('P12-P13' = 'p.1.', 'P128-P129' = 'p.2.', 'P73-P74' = 'p.3.', 'P41-P42' = 'p.4.', 'P6-P7' = 'p.5.')

CSp_tmp <- CSp_raw %>% 
  filter(str_detect(CSp, 'P12-P13')) # repeat for each variables

CSp_table[,'P12-P13'] <- sum(CSp_tmp$nb) # repeat for each variables

我有许多数据 Csp_raw 其中 Csp_raw$Csp 的变化,所以我需要一个更有效和可复制的代码。谢谢

wn9m85ua

wn9m85ua1#

您可以按如下方式使用数据表:

library(data.table)
setDT(CSp_raw)

tab = CSp_raw[, .(grp=unlist(strsplit(CSp, ",", FALSE))), by=nb][, .(sm=sum(nb)), by=grp]

         grp    sm
1:   P12-P13 41946
2: P128-P129    67
3:   P73-P74   936
4:   P41-P42   106
5:     P6-P7     1

如果您更喜欢转置的表(如您的请求中所示),您可以简单地对创建的表调用函数transpose

CSp_table = transpose(tab, make.names=TRUE)

   P12-P13 P128-P129 P73-P74 P41-P42 P6-P7
1:   41946        67     936     106     1
cvxl0en2

cvxl0en22#

拆分为新行,然后按总和分组:

library(data.table)
d[, rn := .I
  ][,.(grp = unlist(tstrsplit(CSp, ",", fixed = TRUE))), by = .(rn, nb)
    ][, .(mySum = sum(nb)), by = .(grp)]
#          grp mySum
# 1:   P12-P13 41946
# 2: P128-P129    67
# 3:   P73-P74   936
# 4:   P41-P42   106
# 5:     P6-P7     1

或者使用tidyr:

library(dplyr)
library(tidyr)
d %>% 
  separate_longer_delim(CSp, ",") %>% 
  group_by(CSp) %>% 
  summarise(mySum = sum(nb))
#   CSp       mySum
#   <chr>     <int>
# 1 P12-P13   41946
# 2 P128-P129    67
# 3 P41-P42     106
# 4 P6-P7         1
# 5 P73-P74     936
wkyowqbh

wkyowqbh3#

我喜欢使用splitstackshape::cSplit_e将这种“多选”列转换为二进制列。

splitstackshape::cSplit_e(dt,
                          "CSp",
                          sep = ",",
                          mode = "binary",
                          type = "character", 
                          fill = 0, 
                          drop = TRUE
                          ) %>% 
rename_with(~str_remove(.x,"^CSp_")) %>% 
  summarise(across(`P12-P13`:`P73-P74`, ~sum(nb[.x == 1], na.rm = TRUE) ) ) 
#>   P12-P13 P128-P129 P41-P42 P6-P7 P73-P74
#> 1   41946        67     106     1     936

数据

dt <- read.table(text = "CSp    nb
P12-P13 41671
P12-P13,P128-P129   5
P12-P13,P128-P129,P73-P74   6
P12-P13,P41-P42 3
P12-P13,P41-P42,P128-P129,P73-P74   2
P12-P13,P41-P42,P73-P74 4
P12-P13,P73-P74 255
P128-P129   18
P128-P129,P73-P74   23
P41-P42 58
P41-P42,P128-P129   1
P41-P42,P128-P129,P73-P74   12
P41-P42,P73-P74 26
P6-P7   1
P73-P74 608", h = TRUE)

创建于2023年3月17日,使用reprex v2.0.2

相关问题