2

我有一个带有 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”。换句话说,我想选择所有 4 波都有“分数”的参与者行。我一直在尝试选择具有所有“Wave”中数据的“ID”的行。到目前为止,我的试用一直基于这个想法:如果参与者拥有所有四个测量值,则 ID 将在数据中出现四次。这就是为什么我试图计算 ID 的数量,

table(data$id) == 4

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

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

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

4

5 回答 5

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)), ]
于 2019-02-19T10:42:01.937 回答
0

与其喂食table(data$ID),不如尝试

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

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

于 2019-02-19T10:35:21.047 回答
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

顺便说一句:始终确保?<name>您没有将任何现有函数名称定义为对象名称,这将为您节省很多麻烦。在您的情况下?data,在加载对象之前键入一个新的会话。)

数据

> dput(d)
structure(list(ID = c(1001L, 1001L, 1001L, 1001L, 1002L, 1002L, 
1003L, 1003L, 1003L, 1003L, 1004L, 1005L, 1005L, 1006L, 1006L, 
1006L, 1006L), Wave = c(1L, 2L, 3L, 4L, 1L, 3L, 1L, 2L, 3L, 4L, 
1L, 1L, 2L, 1L, 2L, 3L, 4L), Score = c(28L, 27L, 28L, 26L, 30L, 
30L, 30L, 30L, 29L, 28L, 22L, 20L, 18L, 22L, 23L, 25L, 19L)), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15", "16", "17"))
于 2019-02-19T10:48:28.050 回答
0

这是一个快速的data.table答案。

  library(data.table)
  dt <- structure(list(ID = c(1001, 1001, 1001, 1001, 1002, 1002, 1003, 
  1003, 1003, 1003, 1004, 1005, 1005, 1006, 1006, 1006, 1006), 
Wave = c(1, 2, 3, 4, 1, 3, 1, 2, 3, 4, 1, 1, 2, 1, 2, 3, 
4), Score = c(28, 27, 28, 26, 30, 30, 30, 30, 29, 28, 22, 
20, 18, 22, 23, 25, 19)), row.names = c(NA, -17L), class = c("data.table", 
"data.frame"))

dt[ , .(Score, N = uniqueN(.SD)) , by = list(ID), .SDcols = c("Wave")][N == 4,]

 >   ID Score N
 1: 1001    28 4
 2: 1001    27 4
 3: 1001    28 4
 4: 1001    26 4
 5: 1003    30 4
 6: 1003    30 4
 7: 1003    29 4
 8: 1003    28 4
 9: 1006    22 4
10: 1006    23 4
11: 1006    25 4
12: 1006    19 4
于 2019-02-19T15:27:41.197 回答
0

为了完整起见,这里有两种data.table解决方案。两者都识别那些IDs 的Wave值为 1 到 4。一种方法使用子集,另一种方法是加入。

子集

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)
于 2019-02-21T21:27:33.850 回答