创建一个列表,从开始计数到当前值。

3

我是一名有用的助手,可以为您翻译以下内容。这是一个数据表:

Name     Person     Date
A        1          1/1/2004
A        2          1/3/2004
A        3          1/9/2004 
B        4          1/7/2004
B        5          1/10/2004 
B        6          1/17/2004

我将尝试创建一个类似于以下格式的新数据表格:
Name     Person     Date
A        1          1/1/2004
A        2          1/1/2004
A        2          1/3/2004
A        3          1/1/2004
A        3          1/3/2004
A        3          1/9/2004
B        4          1/7/2004
B        5          1/7/2004
B        5          1/10/2004
B        6          1/7/2004
B        6          1/10/2004
B        6          1/17/2004

日期从名称组的最小日期开始计算。

到目前为止,我已经做了类似于这样的事情:

data$D = ave(data$Date, data$Name, FUN=min)
diff =  data$Date - data$D
sequence(diff) + rep(data$D,diff)

然而,这只会得到一个重复计算中间日期的结果。是否有一种简单的方法从最小日期开始扩展?谢谢!

你的数据集是以 data.table 格式存在,还是你所说的“data table”只是指 data.frame - David Arenburg
它是以data.table格式呈现的,但我也可以使用data.frame格式。谢谢! - James Schwartz
@AlbertLu。抱歉,我以为你在使用代码中的data.frame。 - akrun
@akrun 我也可以轻松地转换为 data.frame。这不是问题,谢谢! - James Schwartz
@akrun,顺便说一下,dplyrdata.table对象很搭配,所以你的第二个解决方案应该没问题。 - David Arenburg
@David Arenburg和Albert Liu,感谢你们的回复。 - akrun
3个回答

4

看起来你正在寻找一个data.table的解决方案,下面就是:

library(data.table)
setDT(data)[, list(Person = rep(Person, seq_len(.N)),
                   Date = Date[sequence(seq_len(.N))]), by = Name]

#     Name Person      Date
#  1:    A      1  1/1/2004
#  2:    A      2  1/1/2004
#  3:    A      2  1/3/2004
#  4:    A      3  1/1/2004
#  5:    A      3  1/3/2004
#  6:    A      3  1/9/2004
#  7:    B      4  1/7/2004
#  8:    B      5  1/7/2004
#  9:    B      5 1/10/2004
# 10:    B      6  1/7/2004
# 11:    B      6 1/10/2004
# 12:    B      6 1/17/2004

编辑

这是用于回答问题的数据集。


data <- structure(list(Name = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("A", 
        "B"), class = "factor"), Person = 1:6, Date = structure(c(1L, 
        4L, 6L, 5L, 2L, 3L), .Label = c("1/1/2004", "1/10/2004", "1/17/2004", 
        "1/3/2004", "1/7/2004", "1/9/2004"), class = "factor")), .Names = c("Name", 
         "Person", "Date"), class = "data.frame", row.names = c(NA, -6L
         ))

谢谢您的帖子,当我尝试运行代码时,它会显示“意外的“=”” 的信息。这是一个 data.table 的问题吗?谢谢! - James Schwartz
当我运行它时没有错误。请看我的编辑,我已经发布了我使用的数据集。 - David Arenburg
我是不是漏掉了什么,或者"A 2"和"B 5"似乎与期望的输出不匹配? - alexis_laz

3
如果dat是数据集。
res <- do.call(rbind,lapply(split(dat, dat$Name),
     function(x) {
     Date1 <- as.Date(x$Date, "%m/%d/%Y")
     x <- x[order(Date1),]
     indx <- seq_len(nrow(x))
     cbind(x[rep(indx,indx), 1:2], Date=x[sequence(indx),3])}))

 row.names(res) <- 1:nrow(res)
 res
#  Name Person     Date
#1     A      1    1/1/2004
#2     A      2    1/1/2004
#3     A      2    1/3/2004
#4     A      3    1/1/2004
#5     A      3    1/3/2004
#6     A      3    1/9/2004
#7     B      4    1/7/2004
#8     B      5    1/7/2004
#9     B      5   1/10/2004
#10    B      6    1/7/2004
#11    B      6   1/10/2004
#12    B      6   1/17/2004

使用dplyr
dat %>% 
group_by(Name) %>%
mutate(Date1= as.Date(Date, "%m/%d/%Y")) %>% 
arrange(Name, Date1) %>% 
mutate(N= row_number()) %>% 
do(data.frame(.[rep(.$N, .$N),1:2], Date=.[sequence(.$N),3],stringsAsFactors=F))

#   Name Person      Date
#1     A      1  1/1/2004
#2     A      2  1/1/2004
#3     A      2  1/3/2004
#4     A      3  1/1/2004
#5     A      3  1/3/2004
#6     A      3  1/9/2004
#7     B      4  1/7/2004
#8     B      5  1/7/2004
#9     B      5 1/10/2004
#10    B      6  1/7/2004
#11    B      6 1/10/2004
#12    B      6 1/17/2004

2

嵌套的 lapply:

#dummy data
df <- read.table(text="Name     Person     Date
A        1          1/1/2004
A        2          1/3/2004
A        3          1/9/2004 
B        4          1/7/2004
B        5          1/10/2004 
B        6          1/17/2004",header=TRUE)

#convert to date, to be used for min()
df$Date <- as.Date(df$Date,"%m/%d/%Y")

#result
res <- 
  do.call(rbind,
          lapply(split(df,df$Name),
                 function(i){
                   do.call(rbind,
                           lapply(unique(i$Person),
                                  function(j){
                                    d <- i[ i$Date<=min(i[ i$Person==j,"Date"]),]
                                    d$Person <- j
                                    return(d)}))
                 })
  )

# Name Person       Date
# A.1     A      1 2004-01-01
# A.2     A      2 2004-01-01
# A.3     A      2 2004-01-03
# A.4     A      3 2004-01-01
# A.5     A      3 2004-01-03
# A.6     A      3 2004-01-09
# B.4     B      4 2004-01-07
# B.41    B      5 2004-01-07
# B.5     B      5 2004-01-10
# B.42    B      6 2004-01-07
# B.51    B      6 2004-01-10
# B.6     B      6 2004-01-17

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接