2013-09-30 23 views
0

我處理的數據集是在寬格式,如在轉換數據文件,以適應序混合模型中的R

> data=read.csv("http://www.kuleuven.be/bio/ento/temp/data.csv") 
> data 
    factor1 factor2 count_1 count_2 count_3 
1  a  a  1  2  0 
2  a  b  3  0  0 
3  b  a  1  2  3 
4  b  b  2  2  0 
5  c  a  3  4  0 
6  c  b  1  1  0 

其中乘數1和乘數2是該我想不同的因素(事實上​​我有2個以上,但這不應該太重要),count_1到count_3是依次序(3> 2> 1)的積極互動計數。我現在想這個數據集轉換爲長格式,要達到這樣的

factor1 factor2 aggression 
1  a  a   1 
2  a  a   2 
3  a  a   2 
4  a  b   1 
5  a  b   1 
6  a  b   1 
7  b  a   1 
8  b  a   2 
9  b  a   2 
10  b  a   3 
11  b  a   3 
12  b  a   3 
13  b  b   1 
14  b  b   1 
15  b  b   2 
16  b  b   2 
17  c  a   1 
18  c  a   1 
19  c  a   1 
20  c  a   2 
21  c  a   2 
22  c  a   2 
23  c  a   2 
24  c  b   1 
25  c  b   2 

會有人碰巧知道如何做到這一點,而不使用...來循環,例如使用包reshape2? (我意識到它應該使用melt工作,但我只是還沒有能夠找出正確的語法)

編輯:對於那些也會碰巧需要這種功能,這裏是Ananda的答案下面裹成一個小功能:

widetolong.ordinal<-function(data,factors,responses,responsename) { 
    library(reshape2) 
    data$ID=1:nrow(data) # add an ID to preserve row order 
    dL=melt(data, id.vars=c("ID", factors)) # `melt` the data 
    dL=dL[order(dL$ID), ] # sort the molten data 
    dL[,responsename]=match(dL$variable,responses) # convert reponses to ordinal scores 
    dL[,responsename]=factor(dL[,responsename],ordered=T) 
    dL=dL[dL$value != 0, ] # drop rows where `value == 0` 
    out=dL[rep(rownames(dL), dL$value), c(factors, responsename)] # use `rep` to "expand" `data.frame` & drop unwanted columns 
    rownames(out) <- NULL 
    return(out) 
    } 

    # example 
    data <- read.csv("http://www.kuleuven.be/bio/ento/temp/data.csv") 
    widetolong.ordinal(data,c("factor1","factor2"),c("count_1","count_2","count_3"),"aggression") 
+1

在'reshape2'包一看'melt'。通過簡單的例子[這裏](http://www.cookbook-r.com/Manipulating_data/Converting_data_between_wide_and_long_format/),我相信你將能夠識別出相應的'id.vars'和'measure.vars'你自己的數據。 – Henrik

+0

我認爲我唯一使用SPSS的方法就是完成這個任務。 – PascalVKooten

+0

@AnandaMahto:對於我這個有點長的例子感到抱歉 - 我現在編輯它來給出一個更抽象和簡單的例子 - 並且感謝Henrik指針 - 我意識到融化可能是要走的路,但還沒有想出來正確的語法雖然爲我的目的... –

回答

2

melt從「reshape2」只會讓你的方式部分是通過這個問題。走的方式休息,你只需要使用rep從基礎R:

data <- read.csv("http://www.kuleuven.be/bio/ento/temp/data.csv") 
library(reshape2) 

## Add an ID if the row order is importantt o you 
data$ID <- 1:nrow(data) 

## `melt` the data 
dL <- melt(data, id.vars=c("ID", "factor1", "factor2")) 

## Sort the molten data, if necessary 
dL <- dL[order(dL$ID), ] 

## Extract the numeric portion of the "variable" variable 
dL$aggression <- gsub("count_", "", dL$variable) 

## Drop rows where `value == 0` 
dL <- dL[dL$value != 0, ] 

## Use `rep` to "expand" your `data.frame`. 
## Drop any unwanted columns at this point. 
out <- dL[rep(rownames(dL), dL$value), c("factor1", "factor2", "aggression")] 

這就是最終輸出的樣子。如果您想刪除有趣的排名,只需使用rownames(out) <- NULL即可。

out 
#  factor1 factor2 aggression 
# 1   a  a   1 
# 7   a  a   2 
# 7.1  a  a   2 
# 2   a  b   1 
# 2.1  a  b   1 
# 2.2  a  b   1 
# 3   b  a   1 
# 9   b  a   2 
# 9.1  b  a   2 
# 15   b  a   3 
# 15.1  b  a   3 
# 15.2  b  a   3 
# 4   b  b   1 
# 4.1  b  b   1 
# 10   b  b   2 
# 10.1  b  b   2 
# 5   c  a   1 
# 5.1  c  a   1 
# 5.2  c  a   1 
# 11   c  a   2 
# 11.1  c  a   2 
# 11.2  c  a   2 
# 11.3  c  a   2 
# 6   c  b   1 
# 12   c  b   2 
+0

感謝數百萬人 - 完美地完成了這項工作! –