我的数据集来自一个由非面向数据的同事设置的excel文件。我的数据是敏感的,所以我不能共享数据集,但我将尝试做一个例子,这样就更容易理解我在说什么。我有一个唯一的标识符列。我的问题是日期列。我有多个日期列。当导入到R中时,部分列导入为dates,而有些列导入为excel日期。然后列中的一些单元格有一个日期字符串(字符类型)。不是所有的字符串都是相同大小的。有的有2的列表,有的有7的列表。
我在努力整理我的数据。我的想法是把所有的收集日期都放在一栏里。我被困在这里了。我可以使用pivot_longer() bc,并不是所有的列都是相同的类型。我无法将excel日期转换为R日期w/out以去掉字符串列表。我可以去掉字符串列表,bc,我遇到了错误:不兼容的长度。我认为我的逻辑流程是错误的,任何向正确方向指出我的建议都会有帮助。我可以查找编码后,我得到了正确的流。
我所拥有的:
Unique.ID Collection.Date1 Test.Result1 Collection.Date2 Test.Result2 Collection.Date3
1 1 12/12/2020 positive 1/1/21 negative 44890
2 2 11/30/20 negative 1/8/21,1/20/21 negative 2/10/21,3/10/21,4/10/21
3 3 1/20/21 negative 44011 positive 44007
4 4 12/1/20 positive 44018 negative 44064
我想要的是:
Unique ID Collection Date Test Result
1 12/12/20 positive
1 1/1/21 negative
1 2/2/21 NA
2 11/30/20 negative
2 1/8/21 negative
2 1//20/21 negative
2 2/10/21 NA
2 3/10/21 NA
2 4/10/21 NA
3 1/20/21 negative
3 3/3/21 positive
3 4/3/21 NA
4 12/1/20 positive
4 3/3/21 negative
4 4/3/21 NA
如果我首先尝试将所有内容转换为日期,则会遇到字符串的bc错误。当我试图展开字符串时,由于它们的长度不同,我会得到一个错误。
发布于 2021-06-14 19:04:26
因为你没有发布真实的数据,所以我们必须对数据集的结构做一些假设。
数据
假设你的数据看起来
structure(list(Unique.ID = c(1, 2, 3, 4), Collection.Date1 = c("12/12/2020",
"11/30/20", "1/20/21", "12/1/20"), Test.Result1 = c("positive",
"negative", "negative", "positive"), Collection.Date2 = c("1/1/21",
"1/8/21,1/20/21", "44011", "44018"), Test.Result2 = c("negative",
"negative", "positive", "negative"), Collection.Date3 = c("44890",
"2/10/21,3/10/21,4/10/21", "44007", "44064")), problems = structure(list(
row = c(1L, 4L), col = c(NA_character_, NA_character_), expected = c("6 columns",
"6 columns"), actual = c("7 columns", "7 columns"), file = c("literal data",
"literal data")), row.names = c(NA, -2L), class = c("tbl_df",
"tbl", "data.frame")), class = c("spec_tbl_df", "tbl_df", "tbl",
"data.frame"), row.names = c(NA, -4L), spec = structure(list(
cols = list(Unique.ID = structure(list(), class = c("collector_double",
"collector")), Collection.Date1 = structure(list(), class = c("collector_character",
"collector")), Test.Result1 = structure(list(), class = c("collector_character",
"collector")), Collection.Date2 = structure(list(), class = c("collector_character",
"collector")), Test.Result2 = structure(list(), class = c("collector_character",
"collector")), Collection.Date3 = structure(list(), class = c("collector_character",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 2L), class = "col_spec"))
或者为了更好的可读性
# A tibble: 4 x 6
Unique.ID Collection.Date1 Test.Result1 Collection.Date2 Test.Result2 Collection.Date3
<dbl> <chr> <chr> <chr> <chr> <chr>
1 1 12/12/2020 positive 1/1/21 negative 44890
2 2 11/30/20 negative 1/8/21,1/20/21 negative 2/10/21,3/10/21,4/10/21
3 3 1/20/21 negative 44011 positive 44007
4 4 12/1/20 positive 44018 negative 44064
注意:这些数据看起来并不太糟糕。我真的能想到更糟糕的数据。如果您的数据有更多问题,下面的工作流可能会失败。
工作流程
我更喜欢使用tidyverse
中包含的包,在本例中是dplyr
、tidyr
和stringr
。
根据您的数据,我将执行以下步骤:
将数据放入一个长format.
转换成代码,这看起来就像
library(tidyr)
library(dplyr)
library(stringr)
df %>%
pivot_longer(-Unique.ID, names_pattern="(.+)(\\d)", names_to=c("name", "no") ) %>%
mutate(value = str_split(value, ",\\s*")) %>%
unnest(value) %>%
pivot_wider(values_fn=list) %>%
unnest(c(Collection.Date, Test.Result)) %>%
mutate(Collection.Date = coalesce(as.Date(Collection.Date, "%m/%d/%y"),
as.Date(as.integer(Collection.Date), origin="1900-01-01"))) %>%
suppressWarnings() %>%
select(-no)
回传
# A tibble: 15 x 3
Unique.ID Collection.Date Test.Result
<dbl> <date> <chr>
1 1 2020-12-12 positive
2 1 2021-01-01 negative
3 1 2022-11-27 NA
4 2 2020-11-30 negative
5 2 2021-01-08 negative
6 2 2021-01-20 negative
7 2 2021-02-10 NA
8 2 2021-03-10 NA
9 2 2021-04-10 NA
10 3 2021-01-20 negative
11 3 2020-07-01 positive
12 3 2020-06-27 NA
13 4 2020-12-01 positive
14 4 2020-07-08 negative
15 4 2020-08-23 NA
https://stackoverflow.com/questions/67974079
复制相似问题