我有一个类似于以下
的数据集id = c(1,1,1,2,2,2,3,3,4)
cycle = c(1,2,3,1,2,3,1,3,2)
value = 1:9
data.frame(id,cycle,value)
> data.frame(id,cycle,value)
id cycle value
1 1 1 1
2 1 2 2
3 1 3 3
4 2 1 4
5 2 2 5
6 2 3 6
7 3 1 7
8 3 3 8
9 4 2 9
所以基本上有一个名为id
的变量标识样本,一个名为cycle
的变量标识时间点,一个名为value
的变量标识该时间点的值。
如您所见,样本3没有循环2数据,样本4缺少循环1和3数据。我想知道的是有一种方法可以在循环外运行命令,以便将数据放置在没有数据的地方NA
。所以我希望我的数据集看起来如下:
> data.frame(id,cycle,value)
id cycle value
1 1 1 1
2 1 2 2
3 1 3 3
4 2 1 4
5 2 2 5
6 2 3 6
7 3 1 7
8 3 2 NA
9 3 3 8
10 4 1 NA
11 4 2 9
12 4 3 NA
我能够通过很多循环和if语句来解决这个问题,但是代码非常冗长且繁琐(我的真实数据集中有更多的列)。
此外,我拥有的样本数量非常大,所以我需要一些可推广的东西。
答案 0 :(得分:4)
使用merge
和expand.grid
,我们可以提出解决方案。 expand.grid
使用所提供的向量的所有组合创建data.frame
(因此您可以使用id
和cycle
变量提供它。通过合并到原始数据(并使用all.x = T
(类似于SQL中的left join
),我们可以使用dat
填充NA
中缺少数据的行。
id = c(1,1,1,2,2,2,3,3,4)
cycle = c(1,2,3,1,2,3,1,3,2)
value = 1:9
dat <- data.frame(id,cycle,value)
grid_dat <- expand.grid(id = 1:4,
cycle = 1:3)
# or you could do (HT @jogo):
# grid_dat <- expand.grid(id = unique(dat$id),
# cycle = unique(dat$cycle))
merge(x = grid_dat, y = dat, by = c('id','cycle'), all.x = T)
id cycle value
1 1 1 1
2 1 2 2
3 1 3 3
4 2 1 4
5 2 2 5
6 2 3 6
7 3 1 7
8 3 2 NA
9 3 3 8
10 4 1 NA
11 4 2 9
12 4 3 NA
答案 1 :(得分:1)
基于包tidyverse
的解决方案。
library(tidyverse)
# Create example data frame
id <- c(1, 1, 1, 2, 2, 2, 3, 3, 4)
cycle <- c(1, 2, 3, 1, 2, 3, 1, 3, 2)
value <- 1:9
dt <- data.frame(id, cycle, value)
# Complete the combination between id and cycle
dt2 <- dt %>% complete(id, cycle)
答案 2 :(得分:1)
以下是data.table
执行交叉加入的解决方案:
library("data.table")
d <- data.table(id = c(1,1,1,2,2,2,3,3,4), cycle = c(1,2,3,1,2,3,1,3,2), value = 1:9)
d[CJ(id=id, cycle=cycle, unique=TRUE), on=.(id,cycle)]