Как обойти ошибку во время изменения фрейма данных с помощью spread()

Я пытаюсь преобразовать длинный кадр данных в широкие и отмеченные случаи. Я поворачиваю его и использую временный вектор, который служит флагом. Он отлично работает с небольшими наборами данных: см. Пример (скопируйте и вставьте в Rstudio), но когда я пытаюсь сделать это на реальных данных, он сообщает об ошибке:

churnTrain3<- spread (churnTrain, key = "состояние", значение = "временный", fill = 0) Ошибка: повторяющиеся идентификаторы для строк (169, 249), (57, 109), (11, 226)

Структурный набор данных актуален для дальнейшей обработки. Есть ли способ обойти эту проблему. Бьюсь об заклад, многие люди пытаются очистить данные и решить ту же проблему. Пожалуйста, помогите мне Вот код: "Пример"первого блока делает небольшой набор данных для хорошей визуализации, как это выглядит лучшеВторой блок "реальных данных" представляет собой нарезанную часть набора данных из библиотеки оттока

library(caret)
library(tidyr)

#example
#============
df <- data.frame(var1 = (1:6),
             var2 = (7:12),
             factors = c("facto1", "facto2", "facto3", "facto3","facto5", "facto1") ,
             flags = c(1, 1, 1, 1, 1, 1)) 
 df

 df2 <- spread(data = df, key = "factors" , value = flags, fill = " ")
 df2
#=============

# real data
#============
 data(churn)

 str(churnTrain)
 churnTrain <- churnTrain[1:250,1:4]
 churnTrain$temporary <-1
 churnTrain3 <- spread(churnTrain, key = "state", value = "temporary", fill = 0)

 str(churnTrain)
 head(churnTrain3)
 str(churnTrain3)
#============

2 ответа

Распределение может поместить только одно уникальное значение в ячейку, которая пересекает "ключ" разброса и остальные данные (в примере оттока: account_length, area_code и international_plan). Таким образом, реальный вопрос заключается в том, как управлять этими дублирующимися записями. Ответ на это зависит от того, что вы пытаетесь сделать. Ниже я приведу одно из возможных решений. Вместо создания фиктивной "временной" переменной я подсчитываю количество эпизодов и использую их в качестве фиктивной переменной. Это может быть сделано очень легко с помощью dplyr:

library(tidyr)
library(dplyr)    
library(C50) # this is one source for the churn data

data(churn)

churnTrain <- churnTrain[1:250,1:4]

churnTrain2 <- churnTrain %>%
    group_by(state, account_length, area_code, international_plan) %>%
    tally %>%
    dplyr::rename(temporary = n)

churnTrain3 <- spread(churnTrain2, key = "state", value = "temporary", fill = 0)

Распространение сейчас работает.

Как отмечают другие, вам нужно ввести уникальный вектор в spread, Мое решение - использовать базу R:

library(C50)

f<- function(df, key){
  if (sum(names(df)==key)==0) stop("No such key");
  u <- unique(df[[key]])
  id <- matrix(0,dim(df)[1],length(u))
  uu <- lapply(df[[key]],function(x)which(u==x)) ## check 43697442 for details
  for(i in 1:dim(df)[1]) id[i,uu[[i]]] <- 1
  colnames(id) = as.character(u)
  return(cbind(df,id));

}

df <- data.frame(var1 = (1:6),
                 var2 = (7:12),
                 factors = c("facto1", "facto2", "facto3", "facto3","facto5", "facto1"))
f(df, key='fact')
f(df, key='factors')

data(churn)
churnTrain <- churnTrain[1:250,1:4]
f(churnTrain, key='state')

Хотя вы можете увидеть цикл for и другие временные переменные внутри f функция, скорость не медленная действительно.

Другие вопросы по тегам