如何在 r 中重复对相同的 rows/ids 进行子集化
How to subset the same rows/ids repeatedly in r
我有一个巨大的数据框,其中包含匹配的病例对照受试者。匹配的 case:control 是 1:3。我正在尝试对案例 ID 重新采样,然后提取相应的控件。
所以,我有一个 ID 向量,其中 ID 可以重复。我想为向量的每个 id 提取案例和控件的数据。案例和匹配的控件具有相同的 case_num。 %in% 总是从数据中获取唯一的 ID。我已经使用 llply 来做到这一点。大约需要 2.5 秒。还有其他有效的方法吗?
我提供了一个简单的示例和我对问题的解决方案。
在我的例子中,id 向量的长度为 1921,该函数必须提取控件 1921 次。所以如果时间可以减少一秒钟,其实会很多,而我将整个过程重复1000次。谢谢!
test_data=
data.frame(id=c(1,1,2,4,4,5,6),value=c('g','e','r','j','a','b','c'))
test_data
id value
1 1 g
2 1 e
3 2 r
4 4 j
5 4 a
6 5 b
7 6 c
id_vec= c(1,4,1,5)
library(plyr)
newdata.list=llply(id_vec, function(x) test_data[test_data$id==x,])
## or if we make our data a data.table then
library(data.table)
test_data= data.table(test_data)
newdata.list=llply(id_vec, function(x) test_data[id==x])
library(dplyr)
newdata.frame= bind_rows(newdata.list) ### making it a dataframe
newdata.frame
id value
1: 1 g
2: 1 e
3: 4 j
4: 4 a
5: 1 g
6: 1 e
7: 5 b
首先将您的数据框拆分为每个 ID 的数据框列表:
split_data = split(test_data, test_data$id)
我的猜测是您可以在这里停下来使用这个列表,其中每个 id
单独,但只有一次。但是,如果您确实需要 id_vec
中每次重复的数据副本,只需使用列表索引:
result = split_data[id_vec]
如果最后你要重新组合成一个数据框,这是非常浪费的。它涉及复制整个数据,而真正需要的只是行号。如果我理解正确的话,您的示例很差,因为案例编号在数据中重复,而您的示例数据具有唯一的 id
s。这是一种方法,在数据和 id_vec
中重复 id
s 以在不制作数据帧副本的情况下重新采样数据:
## new example data
test_data2 = data.frame(id=c(1, 1, 2, 3, 3, 4), value=c('g','e','r','j','a','b'))
id_vec2 = c(3, 1, 2, 3, 4, 1)
rows = lapply(id_vec2, FUN = function(x) which(test_data2$id == x))
result = test_data2[unlist(rows), ]
result
# id value
# 4 3 j
# 5 3 a
# 1 1 g
# 2 1 e
# 3 2 r
# 4.1 3 j
# 5.1 3 a
# 6 4 b
# 1.1 1 g
# 2.1 1 e
我有一个巨大的数据框,其中包含匹配的病例对照受试者。匹配的 case:control 是 1:3。我正在尝试对案例 ID 重新采样,然后提取相应的控件。
所以,我有一个 ID 向量,其中 ID 可以重复。我想为向量的每个 id 提取案例和控件的数据。案例和匹配的控件具有相同的 case_num。 %in% 总是从数据中获取唯一的 ID。我已经使用 llply 来做到这一点。大约需要 2.5 秒。还有其他有效的方法吗?
我提供了一个简单的示例和我对问题的解决方案。
在我的例子中,id 向量的长度为 1921,该函数必须提取控件 1921 次。所以如果时间可以减少一秒钟,其实会很多,而我将整个过程重复1000次。谢谢!
test_data=
data.frame(id=c(1,1,2,4,4,5,6),value=c('g','e','r','j','a','b','c'))
test_data
id value
1 1 g
2 1 e
3 2 r
4 4 j
5 4 a
6 5 b
7 6 c
id_vec= c(1,4,1,5)
library(plyr)
newdata.list=llply(id_vec, function(x) test_data[test_data$id==x,])
## or if we make our data a data.table then
library(data.table)
test_data= data.table(test_data)
newdata.list=llply(id_vec, function(x) test_data[id==x])
library(dplyr)
newdata.frame= bind_rows(newdata.list) ### making it a dataframe
newdata.frame
id value
1: 1 g
2: 1 e
3: 4 j
4: 4 a
5: 1 g
6: 1 e
7: 5 b
首先将您的数据框拆分为每个 ID 的数据框列表:
split_data = split(test_data, test_data$id)
我的猜测是您可以在这里停下来使用这个列表,其中每个 id
单独,但只有一次。但是,如果您确实需要 id_vec
中每次重复的数据副本,只需使用列表索引:
result = split_data[id_vec]
如果最后你要重新组合成一个数据框,这是非常浪费的。它涉及复制整个数据,而真正需要的只是行号。如果我理解正确的话,您的示例很差,因为案例编号在数据中重复,而您的示例数据具有唯一的 id
s。这是一种方法,在数据和 id_vec
中重复 id
s 以在不制作数据帧副本的情况下重新采样数据:
## new example data
test_data2 = data.frame(id=c(1, 1, 2, 3, 3, 4), value=c('g','e','r','j','a','b'))
id_vec2 = c(3, 1, 2, 3, 4, 1)
rows = lapply(id_vec2, FUN = function(x) which(test_data2$id == x))
result = test_data2[unlist(rows), ]
result
# id value
# 4 3 j
# 5 3 a
# 1 1 g
# 2 1 e
# 3 2 r
# 4.1 3 j
# 5.1 3 a
# 6 4 b
# 1.1 1 g
# 2.1 1 e