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)))