R数据帧中计数值出现的可选嵌套循环

R数据帧中计数值出现的可选嵌套循环,r,R,我正在处理一个大型数据集,我需要计算两列具有相同值的次数。以下是数据集的一个示例: id = rep(replicate(4, paste(sample(LETTERS, 3, replace=F), collapse="")), 12500) names = rep(replicate(3125, paste(sample(letters, 5, replace=T), collapse="")), 16) times = sample(c(3,6,24), 50000, replace =

我正在处理一个大型数据集,我需要计算两列具有相同值的次数。以下是数据集的一个示例:

id = rep(replicate(4, paste(sample(LETTERS, 3, replace=F), collapse="")), 12500)
names = rep(replicate(3125, paste(sample(letters, 5, replace=T), collapse="")), 16)
times = sample(c(3,6,24), 50000, replace = T)

df = data.frame(id=id, names=names, times=times)

count <- list()
ids <- as.vector(unique(df$id))
nms <- as.vector(unique(df$names))

for(i in 1:length(ids)){
  vec <- c()
  for(j in 1:length(nms)){
    vec[j] <- nrow(df[df$id == ids[i] & df$names == nms[j], ])
  }
  count[[i]] <- vec
}
输出:

> count
[[1]]
[1] 5 0 0

[[2]]
[1] 0 5 0

[[3]]
[1] 0 0 5

每个列表项表示id,列表向量表示名称计数。换句话说,分别是
as.vector(unique(df$id))
as.vector(unique(df$names))

library(dplyr)
count <- df %>%
  group_by(id, names) %>%
  summarise(n=sum(times))
count
库(dplyr)
计数%
分组依据(id,名称)%>%
总结(n=总和(次))
计数

这是否符合您的要求

library(dplyr)
count <- df %>%
  group_by(id, names) %>%
  summarise(n=sum(times))
count
库(dplyr)
计数%
分组依据(id,名称)%>%
总结(n=总和(次))
计数

不使用plyr和dplyr,您可以将计算时间减少25%

为了节省合理的计算时间,我对数据的前1000行进行了子集划分

library(microbenchmark)
id = rep(replicate(4, paste(sample(LETTERS, 3, replace=F), collapse="")), 12500)
names = rep(replicate(3125, paste(sample(letters, 5, replace=T), collapse="")), 16)
times = sample(c(3,6,24), 50000, replace = T)

df = data.frame(id=id, names=names, times=times)
df = df[1:1000,]
ids <- as.vector(unique(df$id))
nms <- as.vector(unique(df$names))

因此,
dplyr的速度要快200倍左右

不使用plyr和dplyr,您可以将计算时间减少25%

为了节省合理的计算时间,我对数据的前1000行进行了子集划分

library(microbenchmark)
id = rep(replicate(4, paste(sample(LETTERS, 3, replace=F), collapse="")), 12500)
names = rep(replicate(3125, paste(sample(letters, 5, replace=T), collapse="")), 16)
times = sample(c(3,6,24), 50000, replace = T)

df = data.frame(id=id, names=names, times=times)
df = df[1:1000,]
ids <- as.vector(unique(df$id))
nms <- as.vector(unique(df$names))

因此,
dplyr的速度要快200倍左右

您可以使用
data.table
,这可能是最快的解决方案:

library(data.table)


# convert your dataset into a data.table
  setDT(df)


output <- df [ , .N, by = .(id, names)]


head(output)
>     id names N
> 1: FYG vlrcd 4
> 2: FAL mjhhs 4
> 3: BZU rfnvc 4
> 4: HJA zhssf 4
> 5: FYG pxtne 4
> 6: FAL qgeqr 4

您可以使用
data.table
,这可能是最快的解决方案:

library(data.table)


# convert your dataset into a data.table
  setDT(df)


output <- df [ , .N, by = .(id, names)]


head(output)
>     id names N
> 1: FYG vlrcd 4
> 2: FAL mjhhs 4
> 3: BZU rfnvc 4
> 4: HJA zhssf 4
> 5: FYG pxtne 4
> 6: FAL qgeqr 4

我看不出
id
name
times
列如何彼此相等。您在哪里定义原始数据帧?我认为
times
是OP想要创建的列,并将其作为预期输出包含在示例中..(?)。。。不知道……我试着用较小的
df
(500行)运行它,但结果计数只是一个4行的列表,每个由125行组成。@TimBiegeleisen我提到id和name字段是随机的
库(data.table);setDT(df)[,(Count=.N),by=list(id,names)]
但这不会给你一个列表…我不知道
id
name
times
列如何彼此相等。您在哪里定义原始数据帧?我认为
times
是OP想要创建的列,并将其作为预期输出包含在示例中..(?)。。。不知道……我试着用较小的
df
(500行)运行它,但结果计数只是一个4行的列表,每个由125行组成。@TimBiegeleisen我提到id和name字段是随机的
库(data.table);setDT(df)[,(Count=.N),by=list(id,names)]
但这不会给你一个列表…用
摘要(N=sum(times))
替换为
摘要(N=N())
以获得计数。不是一个列表,但是将
摘要(n=sum(times))
替换为
摘要(n=n())
以获取计数。不是一个列表,但是这和我在评论中的回答是一样的,我没有发布,因为它的输出与OP的不一样。我期待着OP的回复,如果可以接受的话,然后发布…@Sotos,我很抱歉,我没有看到你的评论。请把你的答案贴出来,没关系。我们可以留下你的答案,因为它是向上的:)这和我在评论中的答案是一样的,我没有发布,因为它的输出与OP的不一样…我希望听到OP的意见,如果它是可以接受的,然后发布…@Sotos,我很抱歉,我没有看到你的评论。请把你的答案贴出来,没关系。我们可以留下你的,因为它是:)
library(data.table)


# convert your dataset into a data.table
  setDT(df)


output <- df [ , .N, by = .(id, names)]


head(output)
>     id names N
> 1: FYG vlrcd 4
> 2: FAL mjhhs 4
> 3: BZU rfnvc 4
> 4: HJA zhssf 4
> 5: FYG pxtne 4
> 6: FAL qgeqr 4
L1 <- as.list(as.data.frame(t(output)))  # or

L2 <- split(output, list(output$id, output$names))  # or

L3 <- split(output, seq(nrow(output)))