2016-07-11 90 views
3

的區別我有212行的DF的形式:採取基於ID

ID visit treatment value1 value2 value3 
1 V0  A  2.6  3.4 .1 
1 V1  A  2.3  4.6 .5 
2 V0  B  1.3  5.4 .6 
3 V0  A  1.6  5.4 .7 
2 V1  B  1.8  4.5 .3 
3 V1  A  1.3  7.3 1.2 

所以Ô有一個列有ID,一個隨訪周和治療,並與價值觀一堆列。我想爲每個ID區分不同的情況,每個ID的處理方式是相同的,它從第0周和第1周開始不會改變。ID不一定按順序排列。這可能嗎?

這將是這樣的:

ID visit treatment value1 value2 value3 
1 v0-v1 A  0.3 -1.2  -.4 

等。

+0

是否只有兩次訪問(0和1)?治療怎麼樣?每個ID的可能值是A-A和A-B? –

+0

您是否有隻有一次訪問的情況?或超過2次訪問? – zx8754

回答

0

我以csv的形式將您的數據與分隔符一起用於測試代碼。 假設我有稱爲inpstack

inpstack<-read.csv("/XXX/input.csv",header=TRUE) 
library("sqldf") 
stack1<-sqldf("select * from inpstack where visit='V0'"); 
stack2<-sqldf("select * from inpstack where visit='V1'"); 
stack3<-sqldf("select a.ID, 'V0-V1' as visit,(a.value1-b.value1) as value1,(a.value2-b.value2) as value2,(a.value3-b.value3) as value3 from stack1 a join stack2 b on a.ID=b.ID") 

在一個數據幀中的數據的stack3 DF具有以下輸出

ID,visit,value1,value2,value3 
1,V0-V1,0.3,-1.2,-0.4 
2,V0-V1,-0.5,0.9,0.3 
3,V0-V1,0.3,-1.9,-0.5 

希望這有助於。我已經使用sqldf庫

這隻會對於上述方案,其中將有2只訪問V0和V1工作

+0

想象一下,而不是3個值列有300 ... – zx8754

+0

Definetly它將是一個繁瑣的任務與300值的工作,我們可能需要一些其他的方法 – Dileep

+0

在問題中指定它有212行與定義的表結構。所以,我認爲它會是相同的,使用上面的代碼 – Dileep

0

也許這是有幫助的

library(dplyr) 
result <- df %>% group_by(ID,treatment) %>% summarise_each(funs(diff,toString(visit)),value1,value2,value3) 
result[1:6] 
4

這裏有一個data.table解決方案:

dt[by=.(ID,treatment),j={ 
    z <- nrow(.SD); 
    c(
     .(visit=paste0(visit[1L],'-',visit[z])), 
     lapply(mget(grep(value=T,'^value',names(.SD))),function(x) x[1L]-x[z]) 
    ); 
}]; 
## ID treatment visit value1 value2 value3 
## 1: 1   A V0-V1 0.3 -1.2 -0.4 
## 2: 2   B V0-V1 -0.5 0.9 0.3 
## 3: 3   A V0-V1 0.3 -1.9 -0.5 

數據

library(data.table); 
dt <- data.table(ID=c(1L,1L,2L,3L,2L,3L),visit=c('V0','V1','V0','V0','V1','V1'),treatment=c(
'A','A','B','A','B','A'),value1=c(2.6,2.3,1.3,1.6,1.8,1.3),value2=c(3.4,4.6,5.4,5.4,4.5,7.3), 
value3=c(0.1,0.5,0.6,0.7,0.3,1.2)); 
0

如果存在的話,每個ID處理兩次訪問,你可以使用aggregate如下:

aggregate(cbind(value1, value2, value3)~ID + treatment, data=df, function(i) i[1L]-i[2L]) 
    ID treatment value1 value2 value3 
1 1   A 0.3 -1.2 -0.4 
2 3   A 0.3 -1.9 -0.5 
3 2   B -0.5 0.9 0.3 

如果設置的是不均衡的,你可以插入一個if聲明,將返回NA或其他一些價值:

aggregate(cbind(value1, value2, value3)~ID + treatment, 
      data=df, function(i) {if(length(i) == 2L) i[1L]-i[2L] else NA})