创建一个复杂的新变量

时间:2013-08-08 16:54:54

标签: r dataframe plyr

我有一个长格式的数据集,其中测量(时间)嵌套在嵌套在人(ID)中的Networkpartners(NP)中,这是一个它看起来像的例子(真正的数据集有超过数千个行):

ID  NP  Time Outcome1 Outcome2
1   11  1    4        NA
1   11  2    3        4
1   11  3    NA       NA
1   12  1    2        3
1   12  2    3        1
1   12  3    3        2
2   21  1    2        4
2   21  2    NA       NA
2   21  3    NA       NA
2   22  1    4        NA
2   22  2    4        3
2   22  3    NA       4

现在我想创建以下新变量“NP.T”:

在特定时间,特定人(ID)的网络伙伴数量(在此测量中,结果1和结果2中没有NA)。换句话说:我想计算在两个结果变量上有一个或没有NAs的NP。而且我不想计算那些在两个结果变量中都有NA的NP。

所以我想创建一个这样的数据集:

ID  NP  Time Outcome1 Outcome2 NP.T
1   11  1    4        NA       2
1   11  2    3        4        2
1   11  3    NA       NA       1
1   12  1    2        3        2
1   12  2    3        1        2
1   12  3    3        2        1
2   21  1    2        4        2
2   21  2    NA       NA       1
2   21  3    NA       NA       1
2   22  1    4        NA       2
2   22  2    4        3        1
2   22  3    NA       4        1

我有早期question中提供的关于如何创建一个变量的解决方案,该变量计算特定人(ID)在特定人员(ID)中的Networkpartners(在两个结果之一中没有NA)的数量时间:

library(plyr)
mydata1<-ddply(mydata,.(ID,Time),transform, NP.T=length(Outcome[which(Outcome !   ="NA")]))

现在,如果有人能帮助我找到有关我具体问题的答案,我将非常感激!

2 个答案:

答案 0 :(得分:1)

我想我必须误解这个问题,因为我不确定你是如何得到预期的结果向量的。如果您希望每个ID /时间组合的NP数量对任一结果都没有NA值,请尝试以下操作。

# data:
mydf <- read.table(text="ID  NP  Time Outcome1 Outcome2
1   11  1    4        NA
1   11  2    3        4
1   11  3    NA       NA
1   12  1    2        3
1   12  2    3        1
1   12  3    3        2
2   21  1    2        4
2   21  2    NA       NA
2   21  3    NA       NA
2   22  1    4        NA
2   22  2    4        3
2   22  3    NA       4",header=TRUE)

# ave:
mydf$NP.T <- with(mydf, ave(NP*as.numeric(rowSums(is.na(cbind(Outcome1,Outcome2)))==0),
                            list(ID,Time),
                            FUN=function(x) sum(unique(x)>0)))
#[1] 1 2 1 1 2 1 1 1 0 1 1 0

如果Arun的评论是正确的,那么这就是你想要的:

mydf$NP.T <- with(mydf, ave(NP*as.numeric(rowSums(is.na(cbind(Outcome1,Outcome2)))<2),
                            list(ID,Time),
                            FUN=function(x) sum(unique(x)>0)))
#[1] 2 2 1 2 2 1 2 1 1 2 1 1

答案 1 :(得分:1)

以下是使用plyr软件包的解决方案,类似于我发布的earlier

mydata<-structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L), NP = c(11L, 11L, 11L, 12L, 12L, 12L, 21L, 21L, 21L, 
22L, 22L, 22L), Time = c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 
1L, 2L, 3L), Outcome1 = c(4L, 3L, NA, 2L, 3L, 3L, 2L, NA, NA, 
4L, 4L, NA), Outcome2 = c(NA, 4L, NA, 3L, 1L, 2L, 4L, NA, NA, 
NA, 3L, 4L)), .Names = c("ID", "NP", "Time", "Outcome1", "Outcome2"
), class = "data.frame", row.names = c(NA, -12L))
> mydata
   ID NP Time Outcome1 Outcome2
1   1 11    1        4       NA
2   1 11    2        3        4
3   1 11    3       NA       NA
4   1 12    1        2        3
5   1 12    2        3        1
6   1 12    3        3        2
7   2 21    1        2        4
8   2 21    2       NA       NA
9   2 21    3       NA       NA
10  2 22    1        4       NA
11  2 22    2        4        3
12  2 22    3       NA        4

mydata1<-ddply(mydata,.(ID,Time),transform,NP.T=length(which(!(Outcome1 =="NA" & Outcome2 =="NA"))))
> mydata1
   ID NP Time Outcome1 Outcome2 NP.T
1   1 11    1        4       NA    2
2   1 12    1        2        3    2
3   1 11    2        3        4    2
4   1 12    2        3        1    2
5   1 11    3       NA       NA    1
6   1 12    3        3        2    1
7   2 21    1        2        4    2
8   2 22    1        4       NA    2
9   2 21    2       NA       NA    1
10  2 22    2        4        3    1
11  2 21    3       NA       NA    1
12  2 22    3       NA        4    1