如何将列表(包含多个元素)转换为字符串而无需转到“ c(“ xxx”,“ xxx”,“ xxx”)“ R

时间:2018-10-01 03:36:31

标签: r list sorting split data.table

library(data.table)

# Target string to convert

DATE_DATA <- c("2015-01-02;2015-01-07;2021-05-02;2019-02-05",
"2017-08-02;2000-01-22;2003-03-07;2017-10-09",
"2013-08-02;2022-06-02;2012-03-15")

# Dataset
DT <- data.table(NAME = c("JOE","MARY","PAUL"),DATE = c(DATE_DATA))

预期结果-在新列调用“期间”中转换DATE列,如下所示: 分割+排序递减= F +唯一年份

#  period
1: 2015,2019,2021
2: 2000,2003,2017
3: 2012,2013,2022

下面的方法我没有达到例外的结果

# 1st approach -- RESULT : created column with class -- "list"

DT[,period:= lapply(strsplit(DT$DATE,";"),
                                 function(x) sort(unique(str_sub(x,1,4)),
                                                  decreasing = FALSE))]

# 2nd approach -- RESULT : created column with class -- "character" but value
#                          turn to "c("xxx", "xxx", "xxx")" , not expected 
#                          "xxx,xxx,xxx"

DT[,period:= as.character(paste(lapply(strsplit(DT$DATE,";"),
                             function(x) sort(unique(str_sub(x,1,4)),
                                              decreasing = FALSE)),collapse = ","))]

我错过了哪一步?预先感谢

3 个答案:

答案 0 :(得分:4)

对于每个DATE,我们可以在“;”上拆分DATE列,将其转换为日期,使用format提取年份,采用唯一的年份,然后使用{ {1}}。

toString

我们可以使用DT$Period <- sapply(DT$DATE, function(x) toString(sort(unique(format(as.Date(strsplit(x, ";")[[1]]), "%Y"))))) DT # NAME DATE Period #1: JOE 2015-01-02;2015-01-07;2021-05-02;2019-02-05 2015, 2019, 2021 #2: MARY 2017-08-02;2000-01-22;2003-03-07;2017-10-09 2000, 2003, 2017 #3: PAUL 2013-08-02;2022-06-02;2012-03-15 2012, 2013, 2022 包中的year函数来减少as.Dateformat步骤,从而得到相同的输出。

lubridate

我不是library(lubridate) DT$Period <- sapply(DT$DATE, function(x) toString(sort(unique(year(strsplit(x, ";")[[1]]))))) 专家,但我认为尝试中缺少的是分组(data.table)参数,因为当前它为整个{{1 }}列中,您需要指定by参数中提到的每一行分别需要DATE年。

unique

答案 1 :(得分:2)

我们可以使用gsubscan

DT[,  Period := toString(sort(unique(scan(text=gsub("-\\d+", 
               "", DATE), what = numeric(), sep=";")))), NAME]
DT
#   NAME                                        DATE           Period
#1:  JOE 2015-01-02;2015-01-07;2021-05-02;2019-02-05 2015, 2019, 2021
#2: MARY 2017-08-02;2000-01-22;2003-03-07;2017-10-09 2000, 2003, 2017
#3: PAUL            2013-08-02;2022-06-02;2012-03-15 2012, 2013, 2022

另一个选择是tidyverse,在这里我们通过将;处的'DATE'分割成'NAME',将{Period'转换后的summarise类(sort)的year ed Date,对原始数据集进行联接,并按适当的顺序ymd列(如果需要)

select

答案 2 :(得分:1)

我不确定执行此操作的最快方法,但是相对容易阅读和理解的是:

DT[, period:=sapply(strsplit(DATE, ";"), 
     function(x) paste(sort(unique(year(as.Date(x)))), collapse = ","))]

结果为:

   NAME                                        DATE         period
1:  JOE 2015-01-02;2015-01-07;2021-05-02;2019-02-05 2015,2019,2021
2: MARY 2017-08-02;2000-01-22;2003-03-07;2017-10-09 2000,2003,2017
3: PAUL            2013-08-02;2022-06-02;2012-03-15 2012,2013,2022

strsplit(DATE, ";")将为您提供一列类型列表。这意味着您可以将lapply函数应用于此列,这将占用每一行并对其应用一些函数。然后,只需将日期的字符向量转换为已排序的年份即可。