将具有巨大字符列的数据框重塑为 R 中的多个数字列
Reshaping a dataframe with a huge character column into several numeric columns in R
我有一个包含复杂列 results
的数据集,如 (character
class).
数据样本为here.
date_agenda id_question id_event results
2020-09-04 202009043 7426 "2:1:3|3:1:3|4:8:4|5:1:4|6:7:0|7:7:4|8:7:3|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:1|15:1:3|16:1:0|17:1:3|18:1:3|"
2020-09-04 202009044 7427 "2:1:3|3:1:3|4:8:4|5:1:4|6:7:0|7:7:4|8:7:3|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:3|15:1:3|16:1:0|17:1:3|18:1:3|"
2020-09-04 202009046 7428 "2:1:1|3:1:1|4:8:4|5:1:4|6:7:0|7:7:4|8:7:1|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:3|15:1:1|16:1:0|17:1:1|18:1:1|"
我想将 results
和整个数据帧从 宽格式转换为长格式 ,将最后一列 results
拆分为三个数字列。
例如,2:1:3
是 results
中的一个事件,而此列中有数百个这样的事件。
我想要的输出:
date_agenda id_question id_event mp_id mp_fraction result
2020-09-04 202009043 7426 2 1 3
2020-09-04 202009043 7426 3 1 3
2020-09-04 202009043 7426 4 8 4
2020-09-04 202009043 7426 5 1 4
2020-09-04 202009043 7426 6 7 0
基本上,最初的宽格式(4 列)中的一行将转换为长格式(6 列)中的数百行。
我知道应该用 pivot_longer
、pivot_wider
(或 gather
和 spread
)或者 melt
来完成,但不确定我现在有逻辑了。 我是否应该先将字符拆分成数百列,然后再将其变宽或其他。
感谢提示!谢谢!
我们可以使用 separate_rows
将 "|"
上的 results
拆分为不同的行,使用 separate
将 ":"
拆分为三个不同的列。
library(dplyr)
library(tidyr)
df %>%
separate_rows(results, sep = '\|') %>%
#To remove empty values generated from last "|"
filter(results != '') %>%
separate(results,c("mp_id", "mp_fraction", "result"), sep = ":",convert = TRUE)
# A tibble: 51 x 6
# date_agenda id_question id_event mp_id mp_fraction result
# <chr> <int> <int> <int> <int> <int>
# 1 2020-09-04 202009043 7426 2 1 3
# 2 2020-09-04 202009043 7426 3 1 3
# 3 2020-09-04 202009043 7426 4 8 4
# 4 2020-09-04 202009043 7426 5 1 4
# 5 2020-09-04 202009043 7426 6 7 0
# 6 2020-09-04 202009043 7426 7 7 4
# 7 2020-09-04 202009043 7426 8 7 3
# 8 2020-09-04 202009043 7426 9 3 0
# 9 2020-09-04 202009043 7426 10 8 4
#10 2020-09-04 202009043 7426 11 1 0
# … with 41 more rows
和强制性 data.table
解决方案 ;-)
library(data.table)
DT <- data.table::fread('date_agenda id_question id_event results
2020-09-04 202009043 7426 "2:1:3|3:1:3|4:8:4|5:1:4|6:7:0|7:7:4|8:7:3|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:1|15:1:3|16:1:0|17:1:3|18:1:3|"
2020-09-04 202009044 7427 "2:1:3|3:1:3|4:8:4|5:1:4|6:7:0|7:7:4|8:7:3|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:3|15:1:3|16:1:0|17:1:3|18:1:3|"
2020-09-04 202009046 7428 "2:1:1|3:1:1|4:8:4|5:1:4|6:7:0|7:7:4|8:7:1|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:3|15:1:1|16:1:0|17:1:1|18:1:1|"')
#first, split on pipe
ans <- DT[, list(V2 = unlist(strsplit(results, "[|]", perl = TRUE))),
by=.(date_agenda, id_question, id_event) ]
#the split on colon and drop the temp column
ans[, c("mp_id", "mp_fraction", "result") := tstrsplit( V2, ":") ][, -"V2" ]
输出
# date_agenda id_question id_event mp_id mp_fraction result
# 1: 2020-09-04 202009043 7426 2 1 3
# 2: 2020-09-04 202009043 7426 3 1 3
# 3: 2020-09-04 202009043 7426 4 8 4
# 4: 2020-09-04 202009043 7426 5 1 4
# 5: 2020-09-04 202009043 7426 6 7 0
# 6: 2020-09-04 202009043 7426 7 7 4
# 7: 2020-09-04 202009043 7426 8 7 3
# 8: 2020-09-04 202009043 7426 9 3 0
# 9: 2020-09-04 202009043 7426 10 8 4
# 10: 2020-09-04 202009043 7426 11 1 0
# 11: 2020-09-04 202009043 7426 12 8 4
# 12: 2020-09-04 202009043 7426 13 8 4
# 13: 2020-09-04 202009043 7426 14 8 1
# 14: 2020-09-04 202009043 7426 15 1 3
# 15: 2020-09-04 202009043 7426 16 1 0
# 16: 2020-09-04 202009043 7426 17 1 3
# 17: 2020-09-04 202009043 7426 18 1 3
# 18: 2020-09-04 202009044 7427 2 1 3
# 19: 2020-09-04 202009044 7427 3 1 3
# 20: 2020-09-04 202009044 7427 4 8 4
# 21: 2020-09-04 202009044 7427 5 1 4
# 22: 2020-09-04 202009044 7427 6 7 0
# 23: 2020-09-04 202009044 7427 7 7 4
# 24: 2020-09-04 202009044 7427 8 7 3
# 25: 2020-09-04 202009044 7427 9 3 0
# 26: 2020-09-04 202009044 7427 10 8 4
# 27: 2020-09-04 202009044 7427 11 1 0
# 28: 2020-09-04 202009044 7427 12 8 4
# 29: 2020-09-04 202009044 7427 13 8 4
# 30: 2020-09-04 202009044 7427 14 8 3
# 31: 2020-09-04 202009044 7427 15 1 3
# 32: 2020-09-04 202009044 7427 16 1 0
# 33: 2020-09-04 202009044 7427 17 1 3
# 34: 2020-09-04 202009044 7427 18 1 3
# 35: 2020-09-04 202009046 7428 2 1 1
# 36: 2020-09-04 202009046 7428 3 1 1
# 37: 2020-09-04 202009046 7428 4 8 4
# 38: 2020-09-04 202009046 7428 5 1 4
# 39: 2020-09-04 202009046 7428 6 7 0
# 40: 2020-09-04 202009046 7428 7 7 4
# 41: 2020-09-04 202009046 7428 8 7 1
# 42: 2020-09-04 202009046 7428 9 3 0
# 43: 2020-09-04 202009046 7428 10 8 4
# 44: 2020-09-04 202009046 7428 11 1 0
# 45: 2020-09-04 202009046 7428 12 8 4
# 46: 2020-09-04 202009046 7428 13 8 4
# 47: 2020-09-04 202009046 7428 14 8 3
# 48: 2020-09-04 202009046 7428 15 1 1
# 49: 2020-09-04 202009046 7428 16 1 0
# 50: 2020-09-04 202009046 7428 17 1 1
# 51: 2020-09-04 202009046 7428 18 1 1
# date_agenda id_question id_event mp_id mp_fraction result
我有一个包含复杂列 results
的数据集,如 (character
class).
数据样本为here.
date_agenda id_question id_event results
2020-09-04 202009043 7426 "2:1:3|3:1:3|4:8:4|5:1:4|6:7:0|7:7:4|8:7:3|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:1|15:1:3|16:1:0|17:1:3|18:1:3|"
2020-09-04 202009044 7427 "2:1:3|3:1:3|4:8:4|5:1:4|6:7:0|7:7:4|8:7:3|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:3|15:1:3|16:1:0|17:1:3|18:1:3|"
2020-09-04 202009046 7428 "2:1:1|3:1:1|4:8:4|5:1:4|6:7:0|7:7:4|8:7:1|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:3|15:1:1|16:1:0|17:1:1|18:1:1|"
我想将 results
和整个数据帧从 宽格式转换为长格式 ,将最后一列 results
拆分为三个数字列。
例如,2:1:3
是 results
中的一个事件,而此列中有数百个这样的事件。
我想要的输出:
date_agenda id_question id_event mp_id mp_fraction result
2020-09-04 202009043 7426 2 1 3
2020-09-04 202009043 7426 3 1 3
2020-09-04 202009043 7426 4 8 4
2020-09-04 202009043 7426 5 1 4
2020-09-04 202009043 7426 6 7 0
基本上,最初的宽格式(4 列)中的一行将转换为长格式(6 列)中的数百行。
我知道应该用 pivot_longer
、pivot_wider
(或 gather
和 spread
)或者 melt
来完成,但不确定我现在有逻辑了。 我是否应该先将字符拆分成数百列,然后再将其变宽或其他。
感谢提示!谢谢!
我们可以使用 separate_rows
将 "|"
上的 results
拆分为不同的行,使用 separate
将 ":"
拆分为三个不同的列。
library(dplyr)
library(tidyr)
df %>%
separate_rows(results, sep = '\|') %>%
#To remove empty values generated from last "|"
filter(results != '') %>%
separate(results,c("mp_id", "mp_fraction", "result"), sep = ":",convert = TRUE)
# A tibble: 51 x 6
# date_agenda id_question id_event mp_id mp_fraction result
# <chr> <int> <int> <int> <int> <int>
# 1 2020-09-04 202009043 7426 2 1 3
# 2 2020-09-04 202009043 7426 3 1 3
# 3 2020-09-04 202009043 7426 4 8 4
# 4 2020-09-04 202009043 7426 5 1 4
# 5 2020-09-04 202009043 7426 6 7 0
# 6 2020-09-04 202009043 7426 7 7 4
# 7 2020-09-04 202009043 7426 8 7 3
# 8 2020-09-04 202009043 7426 9 3 0
# 9 2020-09-04 202009043 7426 10 8 4
#10 2020-09-04 202009043 7426 11 1 0
# … with 41 more rows
和强制性 data.table
解决方案 ;-)
library(data.table)
DT <- data.table::fread('date_agenda id_question id_event results
2020-09-04 202009043 7426 "2:1:3|3:1:3|4:8:4|5:1:4|6:7:0|7:7:4|8:7:3|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:1|15:1:3|16:1:0|17:1:3|18:1:3|"
2020-09-04 202009044 7427 "2:1:3|3:1:3|4:8:4|5:1:4|6:7:0|7:7:4|8:7:3|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:3|15:1:3|16:1:0|17:1:3|18:1:3|"
2020-09-04 202009046 7428 "2:1:1|3:1:1|4:8:4|5:1:4|6:7:0|7:7:4|8:7:1|9:3:0|10:8:4|11:1:0|12:8:4|13:8:4|14:8:3|15:1:1|16:1:0|17:1:1|18:1:1|"')
#first, split on pipe
ans <- DT[, list(V2 = unlist(strsplit(results, "[|]", perl = TRUE))),
by=.(date_agenda, id_question, id_event) ]
#the split on colon and drop the temp column
ans[, c("mp_id", "mp_fraction", "result") := tstrsplit( V2, ":") ][, -"V2" ]
输出
# date_agenda id_question id_event mp_id mp_fraction result
# 1: 2020-09-04 202009043 7426 2 1 3
# 2: 2020-09-04 202009043 7426 3 1 3
# 3: 2020-09-04 202009043 7426 4 8 4
# 4: 2020-09-04 202009043 7426 5 1 4
# 5: 2020-09-04 202009043 7426 6 7 0
# 6: 2020-09-04 202009043 7426 7 7 4
# 7: 2020-09-04 202009043 7426 8 7 3
# 8: 2020-09-04 202009043 7426 9 3 0
# 9: 2020-09-04 202009043 7426 10 8 4
# 10: 2020-09-04 202009043 7426 11 1 0
# 11: 2020-09-04 202009043 7426 12 8 4
# 12: 2020-09-04 202009043 7426 13 8 4
# 13: 2020-09-04 202009043 7426 14 8 1
# 14: 2020-09-04 202009043 7426 15 1 3
# 15: 2020-09-04 202009043 7426 16 1 0
# 16: 2020-09-04 202009043 7426 17 1 3
# 17: 2020-09-04 202009043 7426 18 1 3
# 18: 2020-09-04 202009044 7427 2 1 3
# 19: 2020-09-04 202009044 7427 3 1 3
# 20: 2020-09-04 202009044 7427 4 8 4
# 21: 2020-09-04 202009044 7427 5 1 4
# 22: 2020-09-04 202009044 7427 6 7 0
# 23: 2020-09-04 202009044 7427 7 7 4
# 24: 2020-09-04 202009044 7427 8 7 3
# 25: 2020-09-04 202009044 7427 9 3 0
# 26: 2020-09-04 202009044 7427 10 8 4
# 27: 2020-09-04 202009044 7427 11 1 0
# 28: 2020-09-04 202009044 7427 12 8 4
# 29: 2020-09-04 202009044 7427 13 8 4
# 30: 2020-09-04 202009044 7427 14 8 3
# 31: 2020-09-04 202009044 7427 15 1 3
# 32: 2020-09-04 202009044 7427 16 1 0
# 33: 2020-09-04 202009044 7427 17 1 3
# 34: 2020-09-04 202009044 7427 18 1 3
# 35: 2020-09-04 202009046 7428 2 1 1
# 36: 2020-09-04 202009046 7428 3 1 1
# 37: 2020-09-04 202009046 7428 4 8 4
# 38: 2020-09-04 202009046 7428 5 1 4
# 39: 2020-09-04 202009046 7428 6 7 0
# 40: 2020-09-04 202009046 7428 7 7 4
# 41: 2020-09-04 202009046 7428 8 7 1
# 42: 2020-09-04 202009046 7428 9 3 0
# 43: 2020-09-04 202009046 7428 10 8 4
# 44: 2020-09-04 202009046 7428 11 1 0
# 45: 2020-09-04 202009046 7428 12 8 4
# 46: 2020-09-04 202009046 7428 13 8 4
# 47: 2020-09-04 202009046 7428 14 8 3
# 48: 2020-09-04 202009046 7428 15 1 1
# 49: 2020-09-04 202009046 7428 16 1 0
# 50: 2020-09-04 202009046 7428 17 1 1
# 51: 2020-09-04 202009046 7428 18 1 1
# date_agenda id_question id_event mp_id mp_fraction result