假设我有一个如下所示的数据框event_data
:
ID event_one event_two
1 A 1 8
2 B 3 5
3 C 9 13
4 D 9 13
5 E 10 10
6 F 13 15
7 G 13 17
8 H 14 17
9 I 15 19
event
列是从某个初始时间0到事件发生所经过的时间量。因此对于对象C
,event_one
发生在时间9,event_two
发生在时间13。
我想要的是采用times
:
> times = 0:20
> times
[1] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
然后浏览两列,了解每次发生的事情。输出应该如下所示:
time event_ones event_twos
0 0 0
1 1 0
2 0 0
3 1 0
4 0 0
5 0 1
6 0 0
7 0 0
8 0 1
9 2 0
10 1 1
11 0 0
12 0 0
13 2 2
14 1 0
15 1 1
16 0 0
17 0 2
18 0 0
19 0 1
20 0 0
我意识到我可以通过循环遍历times
中的每个元素并迭代地构建表来解决这个问题,但是你真的不应该在R中这样做,我怀疑有更简洁的方法。如果可能的话,它也应该推广到任意多列(我给出的例子是简化的;我的真实数据中有更多这些事件,我必须找到时间计数)。
答案 0 :(得分:2)
不需要包裹。转换为因子和表:
data.frame(
time=0:20,
lapply(
dat[c("event_one","event_two")],
function(x) c(table(factor(x, levels=0:20)))
)
)
不太清楚,您可以使用tabulate
:
data.frame(time=0:20, lapply(dat[c("event_one","event_two")]+1, tabulate, nbins=21))
答案 1 :(得分:1)
df2 <- rbind(data.frame(event="one",time=df$event_one),
data.frame(event="two",time=df$event_two))
times <- data.frame(time=1:20)
library(dplyr)
library(tidyr)
df <- times %>%
left_join(df2, by=c("time" = "time")) %>%
group_by(time,event) %>%
summarize(count=n()) %>%
spread(event, count) %>%
replace_na(list(one = 0, two = 0))
print(df[,1:3], row.names=F)
# A tibble: 20 x 3 # Groups: time [20] time one two <int> <dbl> <dbl> 1 1 1. 0. 2 2 0. 0. 3 3 1. 0. 4 4 0. 0. 5 5 0. 1. 6 6 0. 0. 7 7 0. 0. 8 8 0. 1. 9 9 2. 0. 10 10 1. 1. 11 11 0. 0. 12 12 0. 0. 13 13 2. 2. 14 14 1. 0. 15 15 1. 1. 16 16 0. 0. 17 17 0. 2. 18 18 0. 0. 19 19 0. 1. 20 20 0. 0.
你会注意到print()
我索引的列1:3。这只是因为它还创建了第4个“NA”类别列,表示没有事件的时间。你可以放弃它。
答案 2 :(得分:1)
这需要dplyr
包。首先,我创建一个虚拟数据框。
# Dummy data frame
df <- data.frame(event_one = sample(1:20, 10, replace = TRUE),
event_two = sample(1:20, 10, replace = TRUE))
接下来,我定义一个使用table
计算每个事件的函数,并将输出重新打包为数据框。
# Tabulating function
dain_table <- function(foo){
data.frame(table(foo)) %>%
rename(times = foo)
}
最后,我将函数应用于虚拟数据框中的每一列,并将其连接到所有可能的times
。
# Package it all together
Reduce(function(x, y)left_join(x, y, by = 'times'), lapply(df, dain_table)) %>%
mutate(times = as.numeric(times)) %>%
right_join(data.frame(times = 1:20))
# times Freq.x Freq.y
# 1 1 NA NA
# 2 2 NA NA
# 3 3 NA NA
# 4 4 1 NA
# 5 5 NA NA
# 6 6 NA NA
# 7 7 NA NA
# 8 8 1 1
# 9 9 1 NA
# 10 10 1 1
# 11 11 NA NA
# 12 12 1 NA
# 13 13 1 NA
# 14 14 NA NA
# 15 15 NA NA
# 16 16 NA NA
# 17 17 NA NA
# 18 18 2 2
# 19 19 2 1
# 20 20 NA NA