2017-06-06 1 views
2

J'ai un exemple de script R qui ressemble à ceci:avertissement R: « nombre d'éléments à remplacer est pas un multiple de la longueur de remplacement » semble incorrect

# Create example data 
date <- c("11/09/2016", "11/02/2016", "11/16/2016", "11/23/2016") 
column_two <- c(4, 2, 3, 4) 
# Populate a data frame and make sure the dates have the correct class 
mydata <- data.frame(date, column_two) 
mydata$date <- strptime(mydata$date, format="%m/%d/%Y") 

print("The contents of mydata are:") 
print(mydata) 

# Create a dummy list (or vector, or array, or what is it?) 
foo <- rep(NA, 5) 
print("foo is initialized to:") 
print(foo) 
print("The class of foo is:") 
print(class(foo)) 

earlydate <- min(mydata$date) 
print(sprintf("Earliest date is: %s", earlydate)) 
print("The class of earlydate is:") 
print(class(earlydate)) 
print(sprintf("Length of earliest date is: %d", length(earlydate))) 
print(sprintf("Length of foo[2] is: %d", length(foo[2]))) 

# Attempt to set one variable equal to another 
foo[2] <- earlydate 

print("After assignment, foo looks like this:") 
print(foo) 
print("Now the classes of foo, foo[2], and foo[[2]] are:") 
print(class(foo)) 
print(class(foo[2])) 
print(class(foo[[2]])) 

La sortie imprimée à partir du script ressemble à ceci:

> source("test_warning.R") 
[1] "The contents of mydata are:" 
     date column_two 
1 2016-11-09   4 
2 2016-11-02   2 
3 2016-11-16   3 
4 2016-11-23   4 
[1] "foo is initialized to:" 
[1] NA NA NA NA NA 
[1] "The class of foo is:" 
[1] "logical" 
[1] "Earliest date is: 2016-11-02" 
[1] "The class of earlydate is:" 
[1] "POSIXlt" "POSIXt" 
[1] "Length of earliest date is: 1" 
[1] "Length of foo[2] is: 1" 
[1] "After assignment, foo looks like this:" 
[[1]] 
[1] NA 

[[2]] 
[1] 0 

[[3]] 
[1] NA 

[[4]] 
[1] NA 

[[5]] 
[1] NA 

[1] "Now the classes of foo, foo[2], and foo[[2]] are:" 
[1] "list" 
[1] "list" 
[1] "numeric" 
Warning message: 
In foo[2] <- earlydate : 
    number of items to replace is not a multiple of replacement length 
> 

J'ai tant de questions:

  • Pourquoi est-ce que je reçois un avertissement lorsque foo[2] et earlydate ont manifestement la même longueur? Pourquoi la valeur de foo [2] est-elle définie sur 0 plutôt que sur earlydate?
  • Il est évident que R force automatiquement la variable foo et ses éléments dans de nouvelles classes; pourquoi aucune de ces classes (pour foo, ou foo[2] ou foo[[2]]) ne semble correspondre à la classe ("POSIXlt" "POSIXt") de la variable earlydate?
  • Comment initialiser correctement foo afin qu'il devienne un vecteur, ou une liste, ou une chose de type tableau contenant des éléments individuels qui sont capables de supporter ce type d'affectation de valeur sans déclencher l'avertissement et résultant en ce type de contre-intuitif comportement?

Répondre

1

Eh bien, dans les coulisses de POSIXlt est en fait une liste.

> class(unclass(earlydate)) 
[1] "list" 
> length(unclass(earlydate)) 
[1] 11 

L'affectation prend 0 parce que c'est le premier élément de la liste; c'est le nombre de secondes et est 0 pour earlydate.

> unclass(earlydate)[1] 
$sec 
[1] 0 

Je ne sais pas vraiment pourquoi R ne contraignent pas automatiquement la variable foo dans la classe POSIXlt; Je suppose que la coercition aux dates en général est difficile. Il est clair que faire ici où tout foo est NA, mais que se passe-t-il si l'un des éléments est déjà un entier ou une chaîne? Mais pour le contraindre en premier, utilisez as.POSIXlt.

foo <- rep(as.POSIXlt(NA), 5) 

Selon ce que vous allez faire avec elle, vous trouverez peut-être aussi à l'aide POSIXct être la meilleure solution, comme nous le verrons dans cette réponse à Integer to POSIXlt. Il stocke la date comme le nombre de secondes depuis l'origine, donc n'est pas une liste ci-dessous et est donc mieux adapté pour certains types de calcul et de stockage.