2013-09-30 3 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 

где factor1 и factor2 являются различными факторами, которые я хотел бы (на самом деле у меня больше 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, но я просто еще не смог найти правильный синтаксис)

Редактировать: Для тех из вас, кому также понадобится такая функциональность, вот ответ Ананды ниже обернутый в маленькую функцию:

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'. Проделайте простые примеры [здесь] (http://www.cookbook-r.com/Manipulating_data/Converting_data_between_wide_and_long_format/), и я уверен, что вы сможете идентифицировать соответствующие 'id.vars' и' measure.vars' в ваши собственные данные. – Henrik

+0

Я думаю, что единственное, что я использую SPSS для, - это сделать именно это. – PascalVKooten

+0

@AnandaMahto: извините за мой несколько длинный пример - теперь я отредактировал его, чтобы дать более абстрактный и простой пример - и спасибо Хенрику за указатель - я понял, что расплав, вероятно, был способ пойти, но до сих пор не понял правильный синтаксис, хотя для моей цели ... –

ответ

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

спасибо миллионам - это отлично работает! –

Смежные вопросы