Применение нескольких функций к списку матриц для возврата фрейма данных - PullRequest
0 голосов
/ 21 января 2019

У меня есть такой фрейм данных:

df<- data.frame(year= c(rep("2004", 10), rep("2005", 10), rep("2006", 10), rep("2007", 10)), 
            lev1=c("A", "B", "C", "A", "D", "E", "D", "D", "B","B","C", "A","F","E","A","B",
                       "A", "B","C", "A", "D", "E", "D", "D", "B","B","C", "A","F","E","A", "B", "C", "A", "D","A","F","E","A","B" ), 
            lev2=c("X", "Y", "Z", "X", "W", "T", "W", "W", "Y","Y","Z", "T","U","V","Y","Y",
                      "W", "X","T", "W", "X", "Y", "Z", "X", "W", "T", "W", "W", "Y","Y","Z", "T","U","V","Y","Y",
                   "W", "X","T", "W"))

И есть код для составления списка матриц (Results) для каждого года.lev1 становится строками, а lev2 становится столбцами.Значения внутри матрицы - это количество раз, когда эти два значения встречаются вместе.

sublist=NA
for (i in unique(df$year)){   
sublist[i]<-list(subset(df, df[,1] == i)) 
print(i)
}
Results = list()
for (i in 1: length(unique(sublist))){ 
if (length(sublist[[i]]) > 1 & length(sublist[[i]]) > 1 ){
rows<-unique(sublist[[i]][[2]]) 
cols<-unique(sublist[[i]][[3]]) 
matrix1<- matrix(nrow = length(rows), ncol = length(cols))
df = data.frame(sublist[[i]])
for (k in 1: length(rows)){
  sub_lev1<- subset(df,lev1 == rows[k]) 
  for (j in 1:length(cols)){ 
    sub_lev2<-subset(sub_lev1, lev2 == cols[j]) 
    matrix1[k,j]<-length(sub_lev2[,3])
  }
}
colnames(matrix1) <- cols
rownames(matrix1) <- rows
Results[[i]] = matrix1
}else{next}
}
Results

Я хотел бы запустить отдельную функцию (library("bipartite") networklevel()) для каждого элемента списка, который возвращает несколько значений для нескольких сетевых индексов.Ниже я делаю это индивидуально для каждой матрицы.

d1<-networklevel(Results[[2]])
d2<-networklevel(Results[[3]])
d3<-networklevel(Results[[4]])
d4<-networklevel(Results[[5]])

Требуемый вывод - это фрейм данных, который включает год, имя сетевого индекса и значение для каждого сетевого индекса:

d1<-data.frame(as.list(d1))
d1<- melt(d1)
d1$year<-rep("2004", length(d1))

d2<-data.frame(as.list(d2))
d2<- melt(d2)
d2$year<-rep("2005", length(d2))

d3<-data.frame(as.list(d3))
d3<- melt(d3)
d3$year<-rep("2006", length(d3))

d4<-data.frame(as.list(d4))
d4<- melt(d4)
d4$year<-rep("2007", length(d4))

output<- rbind(d1,d2,d3, d4)

У меня есть несколько проблем:1) по какой-то причине вышеприведенный цикл возвращает первую матрицу как NULL.Как мне это исправить?2) Когда матрицы индексируются в Results, они не индексируются в year, а скорее 1-5.Я хотел бы настроить цикл так, чтобы название года было проиндексировано.Я полагаю, что это облегчит создание выходного потока вниз по течению.

Я попробовал следующее, чтобы вернуть сетевые индексы для каждого элемента списка без успеха:

output<- lapply(mylist, FUN= function(x) networklevel(x)

Я был бы признателен за любую помощь при запуске networklevel для всех элементов списка водин раз.По умолчанию networklevel - возвращать несколько сетевых индексов, поэтому мне нужно решение для запуска networklevel и возврата всех этих индексов для каждой матрицы в организованный фрейм данных, который указывает год, в котором матрица пришла.В моем фактическом наборе данных у меня есть данные за 20 лет, поэтому было бы наиболее эффективно найти решение, которое мешает мне делать это для каждого года / матрицы отдельно.

1 Ответ

0 голосов
/ 21 января 2019

Ваша первая проблема:

1) по какой-то причине вышеприведенный цикл возвращает первую матрицу как NULL.Как мне это исправить?

измените sublist <- NA на sublist <- NULL, NA не будет удален из объекта sublist при запуске цикла for, и именно поэтому первая матрица будет NULL,R переводит в подмножество, где year == NA, и это не будет работать.

Второй выпуск:

2) Когда матрицы индексируются в результатах, они не индексируются по годам, а 1-5.Я хотел бы настроить цикл так, чтобы название года было проиндексировано.

Я бы попробовал что-то вроде этого names(Results) <- c("2004", "2005", "2006", "2007")

Третий выпуск:

зацикливание вывода

В вашем приложениивам не нужно создавать function(x) просто вызовите networklevel вот так output <- lapply(Results, bipartite::networklevel)

Затем вы можете сделать что-то вроде этого, чтобы поместить его в df / matrix:

#get to matrix
dfoutput <- do.call(rbind, output)
#add row names as variable - in your case it is year of analysis
dfoutput2 <- cbind(dfoutput, nms = row.names(dfoutput))
#convert to df if needed
dfoutput3 <- as.data.frame(dfoutput2)
...