R - 按列内的指示符复制行

  • 本文关键字:指示符 复制 r
  • 更新时间 :
  • 英文 :

Type  Network  Show  Placement  Cost     Dates (chr)
VVVV  AJSS     XGAF  BHGHF      103.00   3/21,3/23

我有看起来像上述数据框片段的数据。我需要查看日期列,并根据观察中指定的日期数量(始终采用逗号分隔的格式,如下所示:1/20,1/23,1/30(,我需要复制用逗号分隔的唯一日期的行。最后,上述所有代码片段都应转换为以下内容。

Type  Network  Show  Placement  Cost     Dates (chr)
VVVV  AJSS     XGAF  BHGHF      103.00   3/21
VVVV  AJSS     XGAF  BHGHF      103.00   3/23

我已经有许多解决方案可以生成","计数,然后我可以使用它来复制行计数,但是无法将唯一日期放入日期列。如果可能的话,我想坚持使用基本 R,但如果它是实现目标所需的,我对任何和所有包都持开放态度。

为清楚起见:对于重复标志。我知道如何复制行,但是如何将用逗号分隔的唯一日期应用于每个新创建的行?

提前感谢您,请注明任何必要的额外信息,我将提供。

unnest()可能是您要找的。

library(dplyr); library(tidyr)
df %>% transform(Dates = strsplit(as.character(Dates), ",")) %>% unnest(Dates)
Source: local data frame [2 x 6]
    Type Network   Show Placement  Cost Dates
  (fctr)  (fctr) (fctr)    (fctr) (dbl) (chr)
1   VVVV    AJSS   XGAF     BHGHF   103  3/21
2   VVVV    AJSS   XGAF     BHGHF   103  3/23

下面是一个基本的 R 解决方案:

## generate data
set.seed(1L); N <- 4L; df <- data.frame(Type=replicate(N,paste(collapse='',rep(sample(LETTERS,1L),4L))),Network=replicate(N,paste(collapse='',sample(LETTERS,4L))),Placement=replicate(N,paste(collapse='',sample(LETTERS,5L))),Cost=round(runif(N,50,150),2L),`Dates (chr)`=replicate(N,paste(collapse=',',gsub('\b0','',format(format='%m/%d',sample(seq(as.Date('2016-01-01'),as.Date('2016-12-31'),1L),sample(1:4,1L)))))),stringsAsFactors=F,check.names=F);
df;
##   Type Network Placement   Cost    Dates (chr)
## 1 GGGG    FWYP     YFPCZ 132.09 10/15,1/9,6/22
## 2 JJJJ    QBEX     KAJUH 114.71 9/10,6/23,11/9
## 3 OOOO    RJSL     MOLES 128.29      3/30,1/26
## 4 XXXX    SYJR     RTCQJ 105.30           4/25

## solution #1
ds <- strsplit(df$`Dates (chr)`,',');
data.frame(c(lapply(df[!names(df)%in%'Dates (chr)'],function(col) rep(col,sapply(ds,length))),list(`Dates (chr)`=unlist(ds))),check.names=F,stringsAsFactors=F);
##   Type Network Placement   Cost Dates (chr)
## 1 GGGG    FWYP     YFPCZ 132.09       10/15
## 2 GGGG    FWYP     YFPCZ 132.09         1/9
## 3 GGGG    FWYP     YFPCZ 132.09        6/22
## 4 JJJJ    QBEX     KAJUH 114.71        9/10
## 5 JJJJ    QBEX     KAJUH 114.71        6/23
## 6 JJJJ    QBEX     KAJUH 114.71        11/9
## 7 OOOO    RJSL     MOLES 128.29        3/30
## 8 OOOO    RJSL     MOLES 128.29        1/26
## 9 XXXX    SYJR     RTCQJ 105.30        4/25

另一种可能性:

## solution #2
ds <- strsplit(df$`Dates (chr)`,',');
df2 <- df[rep(seq_len(nrow(df)),sapply(ds,length)),];
df2$`Dates (chr)` <- unlist(ds);
df2;
##     Type Network Placement   Cost Dates (chr)
## 1   GGGG    FWYP     YFPCZ 132.09       10/15
## 1.1 GGGG    FWYP     YFPCZ 132.09         1/9
## 1.2 GGGG    FWYP     YFPCZ 132.09        6/22
## 2   JJJJ    QBEX     KAJUH 114.71        9/10
## 2.1 JJJJ    QBEX     KAJUH 114.71        6/23
## 2.2 JJJJ    QBEX     KAJUH 114.71        11/9
## 3   OOOO    RJSL     MOLES 128.29        3/30
## 3.1 OOOO    RJSL     MOLES 128.29        1/26
## 4   XXXX    SYJR     RTCQJ 105.30        4/25

这是一个数据表解决方案。使用了 Bgoldst 答案的数据帧

library(data.table);
set.seed(1L); N <- 4L; df <- data.frame(Type=replicate(N,paste(collapse='',rep(sample(LETTERS,1L),4L))),Network=replicate(N,paste(collapse='',sample(LETTERS,4L))),Placement=replicate(N,paste(collapse='',sample(LETTERS,5L))),Cost=round(runif(N,50,150),2L),`Dates (chr)`=replicate(N,paste(collapse=',',gsub('\b0','',format(format='%m/%d',sample(seq(as.Date('2016-01-01'),as.Date('2016-12-31'),1L),sample(1:4,1L)))))),stringsAsFactors=F,check.names=F);

dd  <- as.data.table(df)
merge(dd[,.(Type,Network,Placement,Cost)],dd[,(strsplit(`Dates (chr)`,split = "[,]")),Type],by = "Type");

   Type Network Placement   Cost    V1
1: GGGG    FWYP     YFPCZ 132.09 10/15
2: GGGG    FWYP     YFPCZ 132.09   1/9
3: GGGG    FWYP     YFPCZ 132.09  6/22
4: JJJJ    QBEX     KAJUH 114.71  9/10
5: JJJJ    QBEX     KAJUH 114.71  6/23
6: JJJJ    QBEX     KAJUH 114.71  11/9
7: OOOO    RJSL     MOLES 128.29  3/30
8: OOOO    RJSL     MOLES 128.29  1/26
9: XXXX    SYJR     RTCQJ 105.30  4/25

另一种使用 data.table 的解决方案,也牢记更新:

test <- function(x){
 return (unique(unlist(strsplit(x[['Dates (chr)']],','))))
}
library(data.table);
## creating sample dataset
set.seed(1L); N <- 4L; df <- data.frame(Type=replicate(N,paste(collapse='',rep(sample(LETTERS,1L),4L))),Network=replicate(N,paste(collapse='',sample(LETTERS,4L))),Placement=replicate(N,paste(collapse='',sample(LETTERS,5L))),Cost=round(runif(N,50,150),2L),`Dates (chr)`=replicate(N,paste(collapse=',',gsub('\b0','',format(format='%m/%d',sample(seq(as.Date('2016-01-01'),as.Date('2016-12-31'),1L),sample(1:4,1L)))))),stringsAsFactors=F,check.names=F);
setDT(df)
df[,test(.SD),by=c('Type','Network','Placement','Cost')]
##   Type Network Placement   Cost    V1
##1: GGGG    FWYP     YFPCZ 132.09 10/15
##2: GGGG    FWYP     YFPCZ 132.09   1/9
##3: GGGG    FWYP     YFPCZ 132.09  6/22
##4: JJJJ    QBEX     KAJUH 114.71  9/10
##5: JJJJ    QBEX     KAJUH 114.71  6/23
##6: JJJJ    QBEX     KAJUH 114.71  11/9
##7: OOOO    RJSL     MOLES 128.29  3/30
##8: OOOO    RJSL     MOLES 128.29  1/26
##9: XXXX    SYJR     RTCQJ 105.30  4/25

最新更新