基于成对数据条件的R-子集
我正在尝试根据条件对配对的数据进行子集划分。基于成对数据条件的R-子集,r,merge,subset,R,Merge,Subset,我正在尝试根据条件对配对的数据进行子集划分。 这一对由两个人组成,观察时间为2天 我的样本的主要数据是: 'hldid','cid','pid','diary','sex','day','main1' “hldid”指配对数据标识符 “cid”是成对的数据日标识符 dtaSimple_c = merge(M, W, by = 'cid', suffixes = c('_m', '_w')) 'pid'个人标识符 “日记”日记(每个人必须填写2份日记) “性别”“日期”“主要1”指性别、日期和观
这一对由两个人组成,观察时间为2天 我的样本的主要数据是:
'hldid','cid','pid','diary','sex','day','main1'
“hldid”
指配对数据标识符
“cid”
是成对的数据日标识符
dtaSimple_c = merge(M, W, by = 'cid', suffixes = c('_m', '_w'))
'pid'
个人标识符
“日记”
日记(每个人必须填写2份日记)
“性别”“日期”“主要1”
指性别、日期和观察到的活动
我想做的是根据两个条件对数据进行子集划分:
hldid
必须由2个人组成。
每双鞋都应该由一男一女组成李>
日记
。So 4日记作者hldid
M = filter(dtaSimple, sex == 1)
W = filter(dtaSimple, sex == 2)
按成对日标识符合并
dtaSimple_c = merge(M, W, by = 'cid', suffixes = c('_m', '_w'))
那我就去
cid hldid_m pid_m diary_m sex_m day_m main1_m hldid_w pid_w diary_w sex_w day_w main1_w
1 1250_1 1250 1250_2 1 1 1 0 1250 1250_1 1 2 1 0
2 1250_2 1250 1250_2 2 1 3 0 1250 1250_1 2 2 3 0
3 1294_1 1294 1294_2 1 1 6 0 1294 1294_1 1 2 6 0
4 1294_2 1294 1294_2 2 1 1 0 1294 1294_1 2 2 1 0
我认为这并不令人满意。
每一行指的是每个hldid
的第一个日记,每一列指的是对中的男性或女性
我想保留一行一个人一天的原始数据结构
hldid cid pid diary sex day main1
1 1250 1250_1 1250_1 1 2 1 0
2 1250 1250_2 1250_1 2 2 3 0
3 1250 1250_1 1250_2 1 1 1 0
4 1250 1250_2 1250_2 2 1 3 0
.....
数据:
dtaSimple = structure(
list(
hldid = c(1250, 1250, 1250, 1250, 1294, 1294, 1294, 1294, 1352, 1352),
cid = c("1250_1", "1250_2", "1250_1", "1250_2", "1294_1", "1294_2", "1294_1", "1294_2", "1352_1", "1352_2"),
pid = c("1250_1", "1250_1", "1250_2", "1250_2", "1294_1", "1294_1", "1294_2", "1294_2", "1352_1", "1352_1"),
diary = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L),
sex = c(2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L),
day = c(1L, 3L, 1L, 3L, 6L, 1L, 6L, 1L, 1L, 3L),
main1 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)),
.Names = c("hldid", "cid", "pid", "diary", "sex", "day", "main1"),
row.names = c(NA, 10L),
class = "data.frame"
)
在plyr
库中,有一个函数ddply
,用于通过列值组合进行快速分组和制表。考虑到您需要非常具体的分组计数,我喜欢这方面的ddply
。这将两个ddply()
函数链接在一起,最终根据以下内容筛选出个体:
1) 他们没有两个日记价值观
# calculate the number of diaries by pid (we are looking for exactly two):
diaryByPid <- ddply(dtaSimple,c("pid"),function(x){ length(unique(x$diary))})
# the valid pids have exactly two unique diary values
validPid <- diaryByPid$pid[which(diaryByPid[,2]==2)]
# now subset the original dtaSimple to retain only those matched above
dtaSub <- dtaSimple[which(dtaSimple$pid %in% validPid),]
因为我们只从原始结构中删除了行,所以它的格式保持不变:
head(dtaSub2)
hldid cid pid diary sex day main1
1 1250 1250_1 1250_1 1 2 1 0
2 1250 1250_2 1250_1 2 2 3 0
3 1250 1250_1 1250_2 1 1 1 0
4 1250 1250_2 1250_2 2 1 3 0
5 1294 1294_1 1294_1 1 2 6 0
6 1294 1294_2 1294_1 2 2 1 0
7 1294 1294_1 1294_2 1 1 6 0
8 1294 1294_2 1294_2 2 1 1 0
在plyr
库中,有一个函数ddply
,用于通过列值组合进行快速分组和制表。考虑到您需要非常具体的分组计数,我喜欢这方面的ddply
。这将两个ddply()
函数链接在一起,最终根据以下内容筛选出个体:
1) 他们没有两个日记价值观
# calculate the number of diaries by pid (we are looking for exactly two):
diaryByPid <- ddply(dtaSimple,c("pid"),function(x){ length(unique(x$diary))})
# the valid pids have exactly two unique diary values
validPid <- diaryByPid$pid[which(diaryByPid[,2]==2)]
# now subset the original dtaSimple to retain only those matched above
dtaSub <- dtaSimple[which(dtaSimple$pid %in% validPid),]
因为我们只从原始结构中删除了行,所以它的格式保持不变:
head(dtaSub2)
hldid cid pid diary sex day main1
1 1250 1250_1 1250_1 1 2 1 0
2 1250 1250_2 1250_1 2 2 3 0
3 1250 1250_1 1250_2 1 1 1 0
4 1250 1250_2 1250_2 2 1 3 0
5 1294 1294_1 1294_1 1 2 6 0
6 1294 1294_2 1294_1 2 2 1 0
7 1294 1294_1 1294_2 1 1 6 0
8 1294 1294_2 1294_2 2 1 1 0
听起来您需要按分组变量进行筛选。据我所知,对于每个hldid
,您要确保sex
有两个不同的值,总共有4个观察值
您可以使用filter
和groupby
fromdplyr:
library(dplyr)
dtaSimple %>%
group_by(hldid) %>%
filter(n_distinct(sex) == 2, n() >= 4)
hldid cid pid diary sex day main1
1 1250 1250_1 1250_1 1 2 1 0
2 1250 1250_2 1250_1 2 2 3 0
3 1250 1250_1 1250_2 1 1 1 0
4 1250 1250_2 1250_2 2 1 3 0
5 1294 1294_1 1294_1 1 2 6 0
6 1294 1294_2 1294_1 2 2 1 0
7 1294 1294_1 1294_2 1 1 6 0
8 1294 1294_2 1294_2 2 1 1 0
更改数据集,使一个hldid
没有4个观察值需要进行更彻底的测试:
dtaSimple2 = dtaSimple[-4,]
dtaSimple2 %>%
group_by(hldid) %>%
filter(n_distinct(sex) == 2, n() >= 4)
hldid cid pid diary sex day main1
1 1294 1294_1 1294_1 1 2 6 0
2 1294 1294_2 1294_1 2 2 1 0
3 1294 1294_1 1294_2 1 1 6 0
4 1294 1294_2 1294_2 2 1 1 0
如果每个sex
必须有2个日记条目,一个性别可以有1个条目,另一个性别可以有3个条目,那么您需要稍微不同的策略。也许只要确保你对每个性别和每个id
都有2次以上的观察就可以了
dtaSimple %>%
group_by(hldid) %>%
filter(sum(sex == 1) >= 2, sum(sex == 2) >= 2)
听起来您需要按分组变量进行筛选。据我所知,对于每个hldid
,您要确保sex
有两个不同的值,总共有4个观察值
您可以使用filter
和groupby
fromdplyr:
library(dplyr)
dtaSimple %>%
group_by(hldid) %>%
filter(n_distinct(sex) == 2, n() >= 4)
hldid cid pid diary sex day main1
1 1250 1250_1 1250_1 1 2 1 0
2 1250 1250_2 1250_1 2 2 3 0
3 1250 1250_1 1250_2 1 1 1 0
4 1250 1250_2 1250_2 2 1 3 0
5 1294 1294_1 1294_1 1 2 6 0
6 1294 1294_2 1294_1 2 2 1 0
7 1294 1294_1 1294_2 1 1 6 0
8 1294 1294_2 1294_2 2 1 1 0
更改数据集,使一个hldid
没有4个观察值需要进行更彻底的测试:
dtaSimple2 = dtaSimple[-4,]
dtaSimple2 %>%
group_by(hldid) %>%
filter(n_distinct(sex) == 2, n() >= 4)
hldid cid pid diary sex day main1
1 1294 1294_1 1294_1 1 2 6 0
2 1294 1294_2 1294_1 2 2 1 0
3 1294 1294_1 1294_2 1 1 6 0
4 1294 1294_2 1294_2 2 1 1 0
如果每个sex
必须有2个日记条目,一个性别可以有1个条目,另一个性别可以有3个条目,那么您需要稍微不同的策略。也许只要确保你对每个性别和每个id
都有2次以上的观察就可以了
dtaSimple %>%
group_by(hldid) %>%
filter(sum(sex == 1) >= 2, sum(sex == 2) >= 2)
好的,就在我掌握了ddply
的窍门之后,我开始学习dplyr过滤。R太酷了!好的,就在我掌握了ddply
的窍门之后,我开始学习dplyr过滤。R太酷了!