Select 行包含所有纵向测量值
Select rows with all longitudinal measurements
我有一个包含 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
我想 select 提供 'Score' 的所有四个测量值的“ID”。换句话说,我想要 select 行参与者 'Score' 可用于所有 4 波。
我一直在尝试 select 具有“ID”的行,这些行在所有“Wave”中都有数据。到目前为止,我的试用一直基于这样的想法:如果参与者拥有所有四项测量值,则 ID 将在数据中出现四次。
这就是为什么我试图计算ID的数量,
table(data$id) == 4
虽然它向我显示了数据中出现的每个 ID 的数量,但我无法 select 相应的行。
all.data <- subset(data, subset=table(data$id) == 4)
因为原始数据的长度不同,所以是长格式。 "Length of logical index must be 1 or 2637, not 828" 我需要一个长格式的数据来做进一步的分析,所以我不想改变它。
而不是喂 table(data$ID)
,尝试
ID %in% names(table(data$ID)[table(data$ID)==4])
因为 table
给出了每个 ID
(命名向量)
的出现次数
你可以试试:
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)), ]
我喜欢您的 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>
没有将任何现有函数名称定义为对象名称,这将为您省去很多麻烦。在您的案例在加载对象之前在新会话中键入 ?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"))
这是一个快速的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
为了完整起见,这里有两个data.table
解决方案。两者都确定 Wave
的值是 1 到 4 的那些 ID
。一种方法使用子集,另一种方法是连接。
子集化
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"]
其中returns相同的结果。
数据
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)
我有一个包含 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
我想 select 提供 'Score' 的所有四个测量值的“ID”。换句话说,我想要 select 行参与者 'Score' 可用于所有 4 波。 我一直在尝试 select 具有“ID”的行,这些行在所有“Wave”中都有数据。到目前为止,我的试用一直基于这样的想法:如果参与者拥有所有四项测量值,则 ID 将在数据中出现四次。 这就是为什么我试图计算ID的数量,
table(data$id) == 4
虽然它向我显示了数据中出现的每个 ID 的数量,但我无法 select 相应的行。
all.data <- subset(data, subset=table(data$id) == 4)
因为原始数据的长度不同,所以是长格式。 "Length of logical index must be 1 or 2637, not 828" 我需要一个长格式的数据来做进一步的分析,所以我不想改变它。
而不是喂 table(data$ID)
,尝试
ID %in% names(table(data$ID)[table(data$ID)==4])
因为 table
给出了每个 ID
(命名向量)
你可以试试:
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)), ]
我喜欢您的 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>
没有将任何现有函数名称定义为对象名称,这将为您省去很多麻烦。在您的案例在加载对象之前在新会话中键入 ?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"))
这是一个快速的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
为了完整起见,这里有两个data.table
解决方案。两者都确定 Wave
的值是 1 到 4 的那些 ID
。一种方法使用子集,另一种方法是连接。
子集化
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"]
其中returns相同的结果。
数据
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)