我正在用3列收集R中的日志:
周,探测和观察次数
没有观察时没有记录。
week=c(1,2,2,4)
probe=c("A","C","B","C")
obs=c(2,4,3,1)
logs=data.frame(week,probe,obs)
logs
week probe obs
1 A 2
2 C 4
2 B 3
4 C 1
我想重新格式化数据,以便它包括所有星期和所有探测器,即使没有观察,所以它看起来像这样:
week probe obs
1 A 2
1 B 0
1 C 0
1 D 0
2 A 0
2 B 0
2 C 3
2 D 4
3 A 0
3 B 0
3 C 0
3 D 0
4 A 0
4 B 0
4 C 1
4 D 0
我在这里列出了所有探测器:
allprobes=c("A","B","C","D")
我想看看这几周:
allweeks=c(1:4)
我一直在寻找融化,演员,重塑,但我只能在每个身份或月份获得1行...... 因为我实际上想保留日志的原始格式。 起初看起来很容易但我现在卡住了...... 关于如何以这种方式格式化数据的任何建议?
非常感谢您的帮助。
答案 0 :(得分:9)
基础R中的两个选项:
expand.grid
和merge
:> fullFrame <- expand.grid(allweeks, allprobes)
> names(fullFrame) <- c("week", "probe")
> merge(fullFrame, logs, all = TRUE)
week probe obs
1 1 A 2
2 1 B NA
3 1 C NA
4 1 D NA
5 2 A NA
6 2 B 3
7 2 C 4
8 2 D NA
9 3 A NA
10 3 B NA
11 3 C NA
12 3 D NA
13 4 A NA
14 4 B NA
15 4 C 1
16 4 D NA
expand.grid
将创建“allprobes”和“allweeks”对象的所有可能组合的data.frame
。然后,在使用data.frame
时,我们会重新命名新data.frame
的列,以匹配“日志”merge
中的相关列。参数all = TRUE
告诉merge
使用NA
填写缺失的值。
如果您想要零而不是NA
,请按以下步骤操作:
fullFrame <- expand.grid(allweeks, allprobes)
names(fullFrame) <- c("week", "probe")
finalLogs <- merge(fullFrame, logs, all = TRUE)
finalLogs[is.na(finalLogs)] <- 0
xtabs
如果您将“周”和“探测”转换为包含所有相关级别的因素,那么您只需使用xtabs
中包含的data.frame
:
logs$week <- factor(logs$week, levels=c(1, 2, 3, 4))
logs$probe <- factor(logs$probe, levels=c("A", "B", "C", "D"))
data.frame(xtabs(obs ~ week + probe, logs))
# week probe Freq
# 1 1 A 2
# 2 2 A 0
# 3 3 A 0
# 4 4 A 0
# 5 1 B 0
# 6 2 B 3
# 7 3 B 0
# 8 4 B 0
# 9 1 C 0
# 10 2 C 4
# 11 3 C 0
# 12 4 C 1
# 13 1 D 0
# 14 2 D 0
# 15 3 D 0
# 16 4 D 0
答案 1 :(得分:1)
complete
包中的tidyr
函数对于此操作来说是一个不错的实用程序:
# get all the levels in the factor
logs$probe = factor(logs$probe, levels = allprobes)
logs$week = factor(logs$week, levels = 1:4)
tidyr::complete(logs, week, probe, fill = list(obs = 0))
# # A tibble: 16 × 3
# week probe obs
# <fctr> <fctr> <dbl>
# 1 1 A 2
# 2 1 B 0
# 3 1 C 0
# 4 1 D 0
# 5 2 A 0
# 6 2 B 3
# 7 2 C 4
# 8 2 D 0
# 9 3 A 0
# 10 3 B 0
# 11 3 C 0
# 12 3 D 0
# 13 4 A 0
# 14 4 B 0
# 15 4 C 1
# 16 4 D 0