有条件的数字序列
Numeric sequence with condition
我有一个很大的 data.frame,我想为其生成一个新列(称为 Seq),它有一个顺序值,每次在不同的列中发生更改时都会重新启动。这是 data.frame(省略了列)和名为 Seq 的新列的示例。如您所见,有一个连续计数,但每次有新的 IDPath 时,连续计数都会重新开始。
sequentiel长度可以有不同的长度,有的是1长,有的是300。
IDPath LogTime Seq
AADS 19-06-2015 01:57 1
AADS 19-06-2015 01:55 2
AADS 19-06-2015 01:54 3
AADS 19-06-2015 01:53 4
DHSD 19-06-2015 12:57 1
DHSD 19-06-2015 10:58 2
DHSD 19-06-2015 09:08 3
DHSD 19-06-2015 08:41 4
使用data.table
包,这里有一个方法可以得到你想要的东西:
require(data.table)
setDT(dt)[, Seq:=1:.N, by=IDPath]
# or, as mentioned by @DavidArenburg
setDT(dt)[, Seq:=seq_len(.N), by=IDPath]
dt
# IDPath LogTime Seq
#1: AADS 19-06-2015 01:57 1
#2: AADS 19-06-2015 01:55 2
#3: AADS 19-06-2015 01:54 3
#4: AADS 19-06-2015 01:53 4
#5: DHSD 19-06-2015 12:57 1
#6: DHSD 19-06-2015 10:58 2
#7: DHSD 19-06-2015 09:08 3
#8: DHSD 19-06-2015 08:41 4
强制性 Hadleyverse 答案(基础 R 答案也包括在 Hadleyvese 答案之后):
library(dplyr)
dat <- read.table(text="IDPath LogTime
AADS '19-06-2015 01:57'
AADS '19-06-2015 01:55'
AADS '19-06-2015 01:54'
AADS '19-06-2015 01:53'
DHSD '19-06-2015 12:57'
DHSD '19-06-2015 10:58'
DHSD '19-06-2015 09:08'
DHSD '19-06-2015 08:41' ", header=TRUE, stringsAsFactors=FALSE, quote="'")
mutate(group_by(dat, IDPath), Seq=1:n())
或(通过 David Arenburg)
mutate(group_by(dat, IDPath), Seq=row_number())
或者,如果您喜欢管道:
dat %>%
group_by(IDPath) %>%
mutate(Seq=1:n())
或(通过 David Arenburg)
dat %>%
group_by(IDPath) %>%
mutate(Seq=row_number())
强制性基础 R 答案:
unsplit(lapply(split(dat, dat$IDPath), transform, Seq=1:length(IDPath)), dat$IDPath)
或更惯用的方式(再次通过 David)
with(dat, ave(IDPath, IDPath, FUN = seq_along))
如果它确实是一个巨大的数据框,那么您可能希望从 tbl_dt(dat)
开始,以获得 dplyr
解决方案,但是如果您已经在使用 data.table
.
您还可以使用 data.table
包中的 rleid
函数,该函数专门用于在分组操作中生成 运行-length type id 列:
library(data.table)
setDT(df)[, Seq := rleid(LogTime), by=IDPath]
给出:
> df
IDPath LogTime Seq
1: AADS 19-06-2015:01:57 1
2: AADS 19-06-2015:01:55 2
3: AADS 19-06-2015:01:54 3
4: AADS 19-06-2015:01:53 4
5: DHSD 19-06-2015:12:57 1
6: DHSD 19-06-2015:10:58 2
7: DHSD 19-06-2015:09:08 3
8: DHSD 19-06-2015:08:41 4
另一种选择是使用 rowid
函数:
setDT(df)[, Seq := rowid(IDPath)]
这可能有点冗长,但很简单,
alphabets <- c("a", "a", "b", "c", "c")
df <- data.frame(alphabets)
a <- table(df$alphabets)
k <- 1
for (i in 1:length(a))
{
l <- 1
for(j in 1:a[i])
{
df$seq[k] <- l
k <- k+ 1
l <- l+ 1
}
}
df
# alphabets seq
#1 a 1
#2 a 2
#3 b 1
#4 c 1
#5 c 2
我有一个很大的 data.frame,我想为其生成一个新列(称为 Seq),它有一个顺序值,每次在不同的列中发生更改时都会重新启动。这是 data.frame(省略了列)和名为 Seq 的新列的示例。如您所见,有一个连续计数,但每次有新的 IDPath 时,连续计数都会重新开始。 sequentiel长度可以有不同的长度,有的是1长,有的是300。
IDPath LogTime Seq
AADS 19-06-2015 01:57 1
AADS 19-06-2015 01:55 2
AADS 19-06-2015 01:54 3
AADS 19-06-2015 01:53 4
DHSD 19-06-2015 12:57 1
DHSD 19-06-2015 10:58 2
DHSD 19-06-2015 09:08 3
DHSD 19-06-2015 08:41 4
使用data.table
包,这里有一个方法可以得到你想要的东西:
require(data.table)
setDT(dt)[, Seq:=1:.N, by=IDPath]
# or, as mentioned by @DavidArenburg
setDT(dt)[, Seq:=seq_len(.N), by=IDPath]
dt
# IDPath LogTime Seq
#1: AADS 19-06-2015 01:57 1
#2: AADS 19-06-2015 01:55 2
#3: AADS 19-06-2015 01:54 3
#4: AADS 19-06-2015 01:53 4
#5: DHSD 19-06-2015 12:57 1
#6: DHSD 19-06-2015 10:58 2
#7: DHSD 19-06-2015 09:08 3
#8: DHSD 19-06-2015 08:41 4
强制性 Hadleyverse 答案(基础 R 答案也包括在 Hadleyvese 答案之后):
library(dplyr)
dat <- read.table(text="IDPath LogTime
AADS '19-06-2015 01:57'
AADS '19-06-2015 01:55'
AADS '19-06-2015 01:54'
AADS '19-06-2015 01:53'
DHSD '19-06-2015 12:57'
DHSD '19-06-2015 10:58'
DHSD '19-06-2015 09:08'
DHSD '19-06-2015 08:41' ", header=TRUE, stringsAsFactors=FALSE, quote="'")
mutate(group_by(dat, IDPath), Seq=1:n())
或(通过 David Arenburg)
mutate(group_by(dat, IDPath), Seq=row_number())
或者,如果您喜欢管道:
dat %>%
group_by(IDPath) %>%
mutate(Seq=1:n())
或(通过 David Arenburg)
dat %>%
group_by(IDPath) %>%
mutate(Seq=row_number())
强制性基础 R 答案:
unsplit(lapply(split(dat, dat$IDPath), transform, Seq=1:length(IDPath)), dat$IDPath)
或更惯用的方式(再次通过 David)
with(dat, ave(IDPath, IDPath, FUN = seq_along))
如果它确实是一个巨大的数据框,那么您可能希望从 tbl_dt(dat)
开始,以获得 dplyr
解决方案,但是如果您已经在使用 data.table
.
您还可以使用 data.table
包中的 rleid
函数,该函数专门用于在分组操作中生成 运行-length type id 列:
library(data.table)
setDT(df)[, Seq := rleid(LogTime), by=IDPath]
给出:
> df IDPath LogTime Seq 1: AADS 19-06-2015:01:57 1 2: AADS 19-06-2015:01:55 2 3: AADS 19-06-2015:01:54 3 4: AADS 19-06-2015:01:53 4 5: DHSD 19-06-2015:12:57 1 6: DHSD 19-06-2015:10:58 2 7: DHSD 19-06-2015:09:08 3 8: DHSD 19-06-2015:08:41 4
另一种选择是使用 rowid
函数:
setDT(df)[, Seq := rowid(IDPath)]
这可能有点冗长,但很简单,
alphabets <- c("a", "a", "b", "c", "c")
df <- data.frame(alphabets)
a <- table(df$alphabets)
k <- 1
for (i in 1:length(a))
{
l <- 1
for(j in 1:a[i])
{
df$seq[k] <- l
k <- k+ 1
l <- l+ 1
}
}
df
# alphabets seq
#1 a 1
#2 a 2
#3 b 1
#4 c 1
#5 c 2