Ответ 1
ifelse
- ваш друг.
Использование набора данных Dirk
df <- within(df, X <- ifelse(is.na(X), Y, X))
Я пытаюсь заменить некоторые отсутствующие значения в моих данных на средние значения из аналогичной группы.
Мои данные выглядят следующим образом:
X Y
1 x y
2 x y
3 NA y
4 x y
И я хочу, чтобы это выглядело так:
X Y
1 x y
2 x y
3 y y
4 x y
Я написал это, и он работал
for(i in 1:nrow(data.frame){
if( is.na(data.frame$X[i]) == TRUE){
data.frame$X[i] <- data.frame$Y[i]
}
}
Но мой data.frame составляет почти полмиллиона строк, а инструкции for/if довольно медленные. Я хочу что-то вроде
is.na(data.frame$X) <- data.frame$Y
Но это приводит к ошибке несоответствия размера. Кажется, должна быть команда, которая делает это, но я не могу найти ее здесь в SO или в списке справки R. Любые идеи?
ifelse
- ваш друг.
Использование набора данных Dirk
df <- within(df, X <- ifelse(is.na(X), Y, X))
Просто проинтегрируйте его - булевский индексный тест - это одно выражение, и вы также можете использовать его в задании.
Настройка данных:
R> df <- data.frame(X=c("x", "x", NA, "x"), Y=rep("y",4), stringsAsFactors=FALSE)
R> df
X Y
1 x y
2 x y
3 <NA> y
4 x y
Затем перейдите к вычислению индекса замены и замените:
R> ind <- which( is.na( df$X ) )
R> df[ind, "X"] <- df[ind, "Y"]
что дает желаемый результат:
R> df
X Y
1 x y
2 x y
3 y y
4 x y
R>
К сожалению, я пока не могу комментировать, но, вектурируя некоторый код, в котором были задействованы строки, а также символы, приведенные выше, казалось, не работали. Причина объясняется в этом ответе. Если задействованы символы stringsAsFactors=FALSE
недостаточно, так как R может уже создать факторы из символов. Нужно убедиться, что данные снова становятся символьным символом, например, data.frame(X=as.character(c("x", "x", NA, "x")), Y=as.character(rep("y",4)), stringsAsFactors=FALSE)