Ошибка R в '[<-. Data.frame' C '* temp *',… замена содержит # элементов, нужно # - PullRequest
0 голосов
/ 14 мая 2019

У меня есть функция, которую я выполнял много раз, но теперь выдает ошибку, которую я не понимаю. Я пытаюсь применить функцию над списком. Я не написал функцию, и у меня ограниченный опыт работы с функциями. Итак, я не уверен, как устранить неполадки кода.

функция:

myfun<-function(Year, SampleID, Species, Abundance, resamps) {

  library(vegan)
  counter<-1
  simbaseline<-data.frame(array(NA,dim=c(length(unique(Year)),5)))
  names(simbaseline)<-c("Year", "Jaccard","Horn","Bray","Pearson")

  simnext<-data.frame(array(NA,dim=c(length(unique(Year)),5)))
  names(simnext)<-c("Year", "Jaccard","Horn","Bray","Pearson")

  simhind<-data.frame(array(NA,dim=c(length(unique(Year)),5)))
  names(simhind)<-c("Year", "Jaccard","Horn","Bray","Pearson")

  counter2<-1

  # getting vector with number of samples per year
  nsamples<-c()
  for(y in unique(Year)){
    nsamples<-c(nsamples, length(unique(SampleID[Year==y])))
  }
  t<-1
  minsample<-min(nsamples)
  for(repeats in 1:resamps){
    raref<-data.frame(array(NA,dim=c(1,3)))
    names(raref)<-c("Year","Species","Abundance")
    for(y in unique(Year)){
      #getting samples for this year
      samps<-unique(SampleID[Year==y])
      # re-sampling samples to equalize number of samples
      sam<-as.character(sample(samps,minsample,replace=T))
      # getting data that belongs to bootstraped samples
      rarefyear<-data.frame(SampleID[which(SampleID %in% sam & Year == y)],
                            Species[which(SampleID %in% sam & Year == y)],
                            Abundance[which(SampleID %in% sam & Year == y)])
      names(rarefyear)<-c("SampleID", "Species", "Abundance")
      # calculating pooled abundances of eahc species to store
      spabun<-tapply(as.numeric(rarefyear[,3]),rarefyear[,2],sum)
      spar<-data.frame(rep(y, length(spabun)),names(spabun),spabun, row.names=NULL)
      names(spar)<-c("Year","Species","Abundance")
      raref<-rbind(raref,spar)
      counter<-counter+1
    }
    # calculating year by species table of abundance
    rareftabtemp<-with(raref,tapply(Abundance,list(Year,Species),function(x)x))
    rareftabtemp[is.na(rareftabtemp)]<-0
    Pearsoncor<-cor(t(log(rareftabtemp+1)), method="pearson")
    # calculating between year similarities (NOT DISTANCE!) with Jaccard, Morisita-Horn, Bray and Pearson correlations
    Jacsim<-as.matrix(1-vegdist(rareftabtemp, method="jaccard"))
    Hornsim<-as.matrix(1-vegdist(rareftabtemp, method="horn"))
    Braysim<-as.matrix(1-vegdist(rareftabtemp, method="bray"))
    n<-length(unique(Year))
    simbaseline[counter2:(counter2+n-2),]<-
         cbind(unique(Year)[2:n],Jacsim[2:n],Hornsim[2:n],Braysim[2:n],Pearsoncor[2:n])
    simnext[counter2:(counter2+n-2),]<-
         cbind(unique(Year)[2:n],Jacsim[row(Jacsim)-col(Jacsim)==1],
               Hornsim[row(Hornsim)-col(Hornsim)==1],
               Braysim[row(Braysim)-col(Braysim)==1],
               Pearsoncor[row(Pearsoncor)-col(Pearsoncor)==1])
    # added hindcasting 
    simhind[counter2:(counter2+n-2),]<-
          cbind(unique(Year)[1:(n-1)],
                Jacsim[row(Jacsim) %in% 1:(max(row(Jacsim))-1) & 
                       col(Jacsim)==max(col(Jacsim))],
                Hornsim[row(Hornsim)%in%1:(max(row(Hornsim))-1) & 
                      col(Hornsim)==max(col(Hornsim))],
                Braysim[row(Braysim)%in%1:(max(row(Braysim))-1) &
                      col(Braysim)==max(col(Braysim))], 
                Pearsoncor[row(Pearsoncor)%in%1:(max(row(Pearsoncor))-1) & 
                      col(Pearsoncor)==max(col(Pearsoncor))]) 
    counter2<-counter2+n
  }


  baselinesim<-data.frame(unique(Year)[2:n],
       tapply(simbaseline$Jaccard,simbaseline$Year,mean),
       tapply(simbaseline$Horn,simbaseline$Year,mean),
       tapply(simbaseline$Bray,simbaseline$Year,mean),
       tapply(simbaseline$Pearson,simbaseline$Year,mean))
  names(baselinesim)<-c("Year", "Jaccard","Horn","Bray","Pearson")
  nextsim<-data.frame(unique(Year)[2:n],
       tapply(simnext$Jaccard,simnext$Year,mean),
       tapply(simnext$Horn,simnext$Year,mean),
       tapply(simnext$Bray,simnext$Year,mean),
       tapply(simnext$Pearson,simnext$Year,mean))
  names(nextsim)<-c("Year", "Jaccard","Horn","Bray","Pearson")
  hindcastsim<-data.frame(unique(Year)[1:(n-1)],
       tapply(simhind$Jaccard,simhind$Year,mean),
       tapply(simhind$Horn,simhind$Year,mean),
       tapply(simhind$Bray,simhind$Year,mean),
       tapply(simhind$Pearson,simhind$Year,mean))
  names(hindcastsim)<-c("Year", "Jaccard","Horn","Bray","Pearson")
  a<-list(baselinesim,nextsim,hindcastsim)

  return(a)
}

ошибка:

Ошибка в [<-.data.frame (*tmp*, counter2: (counter2 + n - 2), значение = c (NA,: для замены имеется 2 элемента, необходимо 5

Traceback

6.
stop(sprintf(ngettext(m, "replacement has %d item, need %d", 
    "replacement has %d items, need %d"), m, n * p), domain = NA) 
5.
`[<-.data.frame`(`*tmp*`, counter2:(counter2 + n - 2), , value = structure(c(NA, 
2009), .Dim = 2:1)) 
4.
`[<-`(`*tmp*`, counter2:(counter2 + n - 2), , value = structure(c(NA, 
2009), .Dim = 2:1)) 
3.
myfun(x$Year, x$Bay, x$Species, x$Abundance, 20) 
2.
FUN(X[[i]], ...) 
1.
lapply(summer.split, function(x) myfun(x$Year, x$Bay, 
    x$Species, x$Abundance, 20)) 

Опять же, функция сработала Кто-то, похоже, задавал подобный вопрос раньше, и на него ответил @Marat Talipov, но я не достаточно опытен, чтобы понять, в чем заключалось решение.

Ответ был:

Эта ошибка появляется, когда вам не повезло, и я <- runif (n) <1/2 состоит только из FALSE, то есть перестановок не происходит. Вам необходимо добавить проверку в функцию подкачки, чтобы решить эту проблему. </strong>

Ошибка R в '[<-. Data.frame' ... замена содержит # элементов, необходимо # </a>

Подмножество моих данных можно найти здесь:

https://fil.email/sI4Kyhaj

Данные были разделены "Bay" для создания списка

Обратите внимание, что функция не может выдать ошибку на другом компьютере, потому что она, кажется, периодически.

1 Ответ

1 голос
/ 06 июня 2019

Проблема находится в приведенном ниже коде (и аналогично индексируемому переназначению выражений dataframe в вашем коде):

 simbaseline[counter2:(counter2+n-2),]<-
         cbind(unique(Year)[2:n],Jacsim[2:n],Hornsim[2:n],Braysim[2:n],Pearsoncor[2:n])

Что случилось, так это то, что количество строк, которые вы пытаетесь назначить в левом выражении, не равно правому. Чтобы избежать этого, вы можете использовать промежуточный фрейм данных, заполненный, например, NA s, затем переназначьте временный фрейм данных целевому фрейму данных. Пожалуйста, смотрите смоделированный код ниже с пояснениями, как это можно сделать:

# simulation
df <- data.frame(i = 1:10, l = letters[1:10], stringsAsFactors = FALSE)
head(df)
#   i l
# 1 1 a
# 2 1 1
# 3 a a
# 4 4 d
# 5 5 e
# 6 6 f

# with error
df[1:5, ] <- cbind(1:3, c("a", "b", "c"))
# Error in `[<-.data.frame`(`*tmp*`, 1:5, , value = c("1", "2", "3", "a",  : 
# replacement has 6 items, need 10

# without error
dftemp_in <- cbind(1:3, c("a", "b", "c"))
dftemp_out <- df[1:5, ]
dftemp_out[] <- NA
dftemp_out[seq(nrow(dftemp_in)), ] <- dftemp_in
df[1:5, ] <- dftemp_out
df
# i    l
# 1     1    a
# 2     2    b
# 3     3    c
# 4  <NA> <NA>
# 5  <NA> <NA>
# 6     6    f
# 7     7    g
# 8     8    h
# 9     9    i
# 10   10    j
...