选择具有所有纵向尺寸的行

时间:2019-02-19 10:30:38

标签: r subset longitudinal

我有一个纵向数据集,其中包含ID,Wave(Wave1-4)和Score。这是具有相同结构的示例数据。原始数据的长度大约为2000,共有500名参与者,采用长格式。

   ID   Wave Score
 1 1001 1    28
 2 1001 2    27 
 3 1001 3    28
 4 1001 4    26
 5 1002 1    30
 6 1002 3    30
 7 1003 1    30
 8 1003 2    30
 9 1003 3    29
 10 1003 4   28
 11 1004 1   22
 12 1005 1   20
 13 1005 2   18
 14 1006 1   22
 15 1006 2   23
 16 1006 3   25
 17 1006 4   19

我想选择“得分”的所有四个测量值都可用的“ ID”。换句话说,我想选择参与者行,其中“分数”可用于所有四个wave。   我一直在尝试选择ID为'W'的数据的行。到目前为止,我的试用基于该想法:如果一个参与者进行了所有四项测量,则ID将在数据中出现四次。  这就是为什么我尝试计算ID的数量

table(data$id) == 4

,尽管它显示了出现在数据中的每个ID的数量,但我无法选择相应的行。

all.data <- subset(data, subset=table(data$id) == 4)

因为原始数据的长度不同,所以格式较长。 “逻辑索引的长度必须为1或2637,而不是828”。我将需要一个长格式的数据来进行进一步的分析,因此我希望不要更改它。

5 个答案:

答案 0 :(得分:1)

您可以尝试:

df[as.logical(with(df, ave(Wave, ID, FUN = function(x) length(x) == 4))), ]

     ID Wave Score
1  1001    1    28
2  1001    2    27
3  1001    3    28
4  1001    4    26
7  1003    1    30
8  1003    2    30
9  1003    3    29
10 1003    4    28
14 1006    1    22
15 1006    2    23
16 1006    3    25
17 1006    4    19

或者,如果您想保留基本概念,请对@ jay.sf代码进行一些修改:

df[df$ID %in% names(which(table(df$ID) == 4)), ]

答案 1 :(得分:0)

代替喂table(data$ID),请尝试

ID %in% names(table(data$ID)[table(data$ID)==4])

table为您提供了每个ID(命名向量)的出现次数

答案 2 :(得分:0)

我喜欢您的table()方法。

> table(d$ID) == 4

 1001  1002  1003  1004  1005  1006 
 TRUE FALSE  TRUE FALSE FALSE  TRUE 

有趣的ID虽然在names()中。因此,要使代码正常工作,您可以像这样提取ID

subs <- names(which(table(d$ID) == 4))

并使用%in%获得所需的子集。

all.data <- subset(d, subset=d$ID %in% subs)

结果

> all.data
     ID Wave Score
1  1001    1    28
2  1001    2    27
3  1001    3    28
4  1001    4    26
7  1003    1    30
8  1003    2    30
9  1003    3    29
10 1003    4    28
14 1006    1    22
15 1006    2    23
16 1006    3    25
17 1006    4    19

BTW:始终使用?<name>确保您没有将任何现有的函数名称定义为对象名称,这样可以避免很多麻烦。在您的情况下,键入{{ 1}},然后再重新加载对象。)

数据

?data

答案 3 :(得分:0)

这是一个快速的(df.ne(0)&df.notnull()).sum() Out[305]: agr 3 col1 1 col2 2 dtype: int64 答案。

df.notnull().sum()
Out[322]: 
agr     3
col1    1
col2    2
dtype: int64

答案 4 :(得分:0)

出于完整性考虑,这里有两个data.table解决方案。两者都标识ID的值为{1到4的Wave。一种方法使用子集,另一种方法是加入。

子集

library(data.table)
setDT(df)[ID %in% dt[ , which(uniqueN(Wave) == 4L), by = ID]$ID]
      ID Wave Score
 1: 1001    1    28
 2: 1001    2    27
 3: 1001    3    28
 4: 1001    4    26
 5: 1003    1    30
 6: 1003    2    30
 7: 1003    3    29
 8: 1003    4    28
 9: 1006    1    22
10: 1006    2    23
11: 1006    3    25
12: 1006    4    19

加入

library(data.table)
setDT(df)[df[, .N, .(ID, Wave)][, .N, ID][N == 4L, .(ID)], on = "ID"]

返回相同的结果。

数据

library(data.table)
fread("
rn ID   Wave Score
 1 1001 1    28
 2 1001 2    27 
 3 1001 3    28
 4 1001 4    26
 5 1002 1    30
 6 1002 3    30
 7 1003 1    30
 8 1003 2    30
 9 1003 3    29
 10 1003 4   28
 11 1004 1   22
 12 1005 1   20
 13 1005 2   18
 14 1006 1   22
 15 1006 2   23
 16 1006 3   25
 17 1006 4   19", drop = 1L)