Использование цикла for для получения списка фреймов данных в R - PullRequest
0 голосов
/ 16 мая 2018

split - список фреймов данных, полученных из split () в главном фрейме данных.

После разделения я применяю функцию к каждому фрейму данных в разделенный список.

Здесь функция:

getCustomer <- function(df, numberOfProducts = 3){

Gender <- unique(df$gender)
Segment <- unique(df$Segment)
Net_Discount <- sum(df$Discount * df$Sales)
Number_of_Discounts <- sum(df$Discount>0)
Customer.ID <- unique(df$Customer.ID)
Sales <- sum(df$Sales)
Profit <- sum(df$Profit)
lat <- mean(df$lat)
lon <- mean(df$lon)

productsData <- df %>% arrange(Order.Date) %>% top_n(n =numberOfProducts)

Products <- 0 
Products_Category <- 0
Products_Order_Date <- 0

for (j in 1:numberOfProducts){ 

Products[j] <- productsData %>% select(Product.ID) %>% filter(row_number()==j)
Products_Category[j] <- productsData %>% select(Category) %>% filter(row_number()==j)
  Products_Order_Date[j] <- productsData %>% select(Order.Date) %>% filte(row_number()==j)

  names(Products)[j]<-paste("Product",j)
  names(Products_Category)[j]<-paste("Category Product",j)
  names(Products_Order_Date)[j]<-paste("Order Date Product",j)

  }


  output <- data.frame(Customer.ID, Gender,Segment, Net_Discount, Number_of_Discounts, Sales, Profit, 
                   Products, Products_Category, Products_Order_Date, lon,lat)

return(output[1,])
}

Я получаю правильный ответ для любого элемента из split

getCustomer(splitted[[687]],2)

Я могу даже преуспеть с

customer <- list()
customer[[1]]<- getCustomer(splitted[[1]],2)
customer[[2]]<- getCustomer(splitted[[2]],2)
.
.
.
customer[[1576]]<- getCustomer(splitted[[1576]],2)

То есть я могу эффективно построить весь список customer , присваивая элемент за элементом.

Однако у меня, конечно, нет на это времени (1576 однострочных фреймов данных для назначения в список customer ), поэтому я пытаюсь:

customer <- list()

for (i in 1:length(splitted)){

  customer[[i]]<-getCustomer(splitted[[i]],2)

}

После запуска этого последнего фрагмента кода я получаю:

Error in data.frame(Customer.ID, Gender,  Segment, Net_Discount, Number_of_Discounts, : arguments imply differing number of rows: 0, 1

Я не могу понять эту ошибку, поскольку я могу строить элемент списка клиентов по элементам за один раз.

Буду признателен за вашу помощь.

Решение

Редактирование этого вопроса, чтобы вы знали, что проблема в том, что некоторые фреймы данных в split не имели строк.Поэтому я удалил их (только 3).

for (i in 1:length(splitted)){
l[i]<-nrow(splitted[[i]])  
}

indices<- which(l==0)

splitted<-splitted[-indices]

Просто пришлось удалить 3 образца.На этот раз не было ошибок.Спасибо всем за ваше время.

Ответы [ 3 ]

0 голосов
/ 16 мая 2018

Моя обычная стратегия поиска и устранения неисправностей - запускать его порциями. Если вы используете цикл for, проверьте значение i при возникновении ошибки. С lapply я буду работать порциями по 20 ... и буду продолжать, пока не найдешь, какой фрейм данных в вашем списке вызывает ошибку.

Затем запустите вашу функцию вручную с этим фреймом данных и посмотрите, какой вывод вы получите. Например:

df <- splitted[[30]] # assuming #30 is the problem
numberOfProducts <- 3

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

0 голосов
/ 16 мая 2018

Проблема была в том, что некоторые фреймы данных в разбитых не имели строк. Поэтому я удалил их (только 3).

for (i in 1:length(splitted)){
l[i]<-nrow(splitted[[i]])  
}

indices<- which(l==0)

splitted<-splitted[-indices]

Просто пришлось удалить 3 сэмпла.

На этот раз без ошибок. Спасибо всем за ваше время.

0 голосов
/ 16 мая 2018

Просто используйте lapply, который может применить функцию к каждому элементу списка, возвращая список в процессе:

numberOfProducts <- 2
result <- lapply(splitted, function(x) getCustomer(x, numberOfProducts))

Редактировать:

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

output <- data.frame(Customer.ID, Gender,Segment, Net_Discount, Number_of_Discounts, Sales,
    Profit, Products, Products_Category, Products_Order_Date, lon, lat)
return(ifelse(nrow(output) > 0, output[1,], NA))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...