根据分类变量查找数据集中的常见日期
Finding the common dates in a data set based on a categorical variable
我有一个看起来像这样的数据集:
id eye date notes
1 L 01-01-2000
1 L 01-06-2000
1 R 01-01-2000
1 R 01-03-2000
1 R 01-06-2000
2 L 01-01-2000
2 L 01-04-2000
2 R 01-04-2000
2 R 01-07-2000
2 R 04-09-2001
3 L 01-01-2000
4 L 01-01-2000
4 L 03-03-2001
4 R 03-03-2001
对于每个 id
,我希望能够找到眼睛标记为 L 和 R 的常见日期,然后将其输出为数据框。所以它应该看起来像:
id eye date notes
1 L 01-01-2000
1 L 01-06-2000
1 R 01-01-2000
1 R 01-06-2000
2 L 01-04-2000
2 R 01-04-2000
4 L 03-03-2001
4 R 03-03-2001
我一直在尝试 dplyr
和 plyr
的不同变体(下面的示例),但我似乎无法让它做我想做的事。
data %>% group_by(id) %>% do(Reduce(intersect, list(.$date[.$eye == "L"], .$date[.$eye == "R"])))
ddply(data, .(id), summarize, Reduce(intersect, list(.$date[.$eye == "L"], .$date[.$eye == "R"])))
从语义上看,这两个似乎 "say" 我想让他们做什么,但我没有得到任何清晰的结果。
有什么想法吗?
如果在一个 id-date 有两个观测值时总是有一个 L 和一个 R,就像您的示例数据一样,那么您可以像这样使用 duplicated
:
dat[duplicated(dat[-2]) | duplicated(dat[-2], fromLast = TRUE),]
id eye date
1 1 L 01-01-2000
2 1 L 01-06-2000
3 1 R 01-01-2000
5 1 R 01-06-2000
7 2 L 01-04-2000
8 2 R 01-04-2000
13 4 L 03-03-2001
14 4 R 03-03-2001
如果您需要检查 L 和 R 是否都存在于 id-date 对中,您可以保存以上结果并使用 ave
执行这样的检查
temp <- dat[duplicated(dat[-2]) | duplicated(dat[-2], fromLast = TRUE),]
temp[as.logical(ave(as.character(temp$eye), temp$id, temp$date,
FUN=function(x) all(x %in% c("L", "R")))),]
id eye date
1 1 L 01-01-2000
2 1 L 01-06-2000
3 1 R 01-01-2000
5 1 R 01-06-2000
7 2 L 01-04-2000
8 2 R 01-04-2000
13 4 L 03-03-2001
14 4 R 03-03-2001
对于 dplyr 你可以使用 filter
:
dat %>%
group_by(date) %>%
filter(sum(eye == "L") > 0 & sum(eye == "R") > 0 & !(duplicated(date) & duplicated(eye)))
Source: local data frame [6 x 3]
Groups: date [3]
id eye date
<int> <fctr> <fctr>
1 1 L 01-01-2000
2 1 L 01-06-2000
3 1 R 01-01-2000
4 1 R 01-06-2000
5 2 L 01-04-2000
6 2 R 01-04-2000
我们也可以用data.table
library(data.table)
setDT(df1)[, .SD[(uniqueN(eye)>1) & !duplicated(eye)], date]
# date id eye
#1: 01-01-2000 1 L
#2: 01-01-2000 1 R
#3: 01-06-2000 1 L
#4: 01-06-2000 1 R
#5: 01-04-2000 2 L
#6: 01-04-2000 2 R
另一个:
df <- read.table(header=TRUE, text="id eye date
1 L 01-01-2000
1 L 01-06-2000
1 R 01-01-2000
1 R 01-03-2000
1 R 01-06-2000
2 L 01-01-2000
2 L 01-04-2000
2 R 01-04-2000
2 R 01-07-2000
2 R 04-09-2001
3 L 01-01-2000
4 L 01-01-2000
4 L 03-03-2001
4 R 03-03-2001")
library(dplyr)
left_join(df %>%
group_by(id,date) %>%
summarize(n=n()) %>%
filter(n==2) %>%
select(-n),
df,
by=c("id","date")) %>%
arrange(id,eye,date)
我有一个看起来像这样的数据集:
id eye date notes
1 L 01-01-2000
1 L 01-06-2000
1 R 01-01-2000
1 R 01-03-2000
1 R 01-06-2000
2 L 01-01-2000
2 L 01-04-2000
2 R 01-04-2000
2 R 01-07-2000
2 R 04-09-2001
3 L 01-01-2000
4 L 01-01-2000
4 L 03-03-2001
4 R 03-03-2001
对于每个 id
,我希望能够找到眼睛标记为 L 和 R 的常见日期,然后将其输出为数据框。所以它应该看起来像:
id eye date notes
1 L 01-01-2000
1 L 01-06-2000
1 R 01-01-2000
1 R 01-06-2000
2 L 01-04-2000
2 R 01-04-2000
4 L 03-03-2001
4 R 03-03-2001
我一直在尝试 dplyr
和 plyr
的不同变体(下面的示例),但我似乎无法让它做我想做的事。
data %>% group_by(id) %>% do(Reduce(intersect, list(.$date[.$eye == "L"], .$date[.$eye == "R"])))
ddply(data, .(id), summarize, Reduce(intersect, list(.$date[.$eye == "L"], .$date[.$eye == "R"])))
从语义上看,这两个似乎 "say" 我想让他们做什么,但我没有得到任何清晰的结果。
有什么想法吗?
如果在一个 id-date 有两个观测值时总是有一个 L 和一个 R,就像您的示例数据一样,那么您可以像这样使用 duplicated
:
dat[duplicated(dat[-2]) | duplicated(dat[-2], fromLast = TRUE),]
id eye date
1 1 L 01-01-2000
2 1 L 01-06-2000
3 1 R 01-01-2000
5 1 R 01-06-2000
7 2 L 01-04-2000
8 2 R 01-04-2000
13 4 L 03-03-2001
14 4 R 03-03-2001
如果您需要检查 L 和 R 是否都存在于 id-date 对中,您可以保存以上结果并使用 ave
执行这样的检查
temp <- dat[duplicated(dat[-2]) | duplicated(dat[-2], fromLast = TRUE),]
temp[as.logical(ave(as.character(temp$eye), temp$id, temp$date,
FUN=function(x) all(x %in% c("L", "R")))),]
id eye date
1 1 L 01-01-2000
2 1 L 01-06-2000
3 1 R 01-01-2000
5 1 R 01-06-2000
7 2 L 01-04-2000
8 2 R 01-04-2000
13 4 L 03-03-2001
14 4 R 03-03-2001
对于 dplyr 你可以使用 filter
:
dat %>%
group_by(date) %>%
filter(sum(eye == "L") > 0 & sum(eye == "R") > 0 & !(duplicated(date) & duplicated(eye)))
Source: local data frame [6 x 3]
Groups: date [3]
id eye date
<int> <fctr> <fctr>
1 1 L 01-01-2000
2 1 L 01-06-2000
3 1 R 01-01-2000
4 1 R 01-06-2000
5 2 L 01-04-2000
6 2 R 01-04-2000
我们也可以用data.table
library(data.table)
setDT(df1)[, .SD[(uniqueN(eye)>1) & !duplicated(eye)], date]
# date id eye
#1: 01-01-2000 1 L
#2: 01-01-2000 1 R
#3: 01-06-2000 1 L
#4: 01-06-2000 1 R
#5: 01-04-2000 2 L
#6: 01-04-2000 2 R
另一个:
df <- read.table(header=TRUE, text="id eye date
1 L 01-01-2000
1 L 01-06-2000
1 R 01-01-2000
1 R 01-03-2000
1 R 01-06-2000
2 L 01-01-2000
2 L 01-04-2000
2 R 01-04-2000
2 R 01-07-2000
2 R 04-09-2001
3 L 01-01-2000
4 L 01-01-2000
4 L 03-03-2001
4 R 03-03-2001")
library(dplyr)
left_join(df %>%
group_by(id,date) %>%
summarize(n=n()) %>%
filter(n==2) %>%
select(-n),
df,
by=c("id","date")) %>%
arrange(id,eye,date)