2016-02-21 2 views
-1

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

Кадр данных с данными о Facebook, подготовленный из JSON, содержит столбцы «значения» со значениями списка. Для следующей манипуляции мне нужно иметь только одно значение в столбце. Таким образом, строка 3 на картинке должна быть преобразована в два (с содержанием списка или значением непосредственно):

post_story_adds_by_action_type_unique lifetime list(like = 38) 
post_story_adds_by_action_type_unique lifetime list(share = 11) 

Если есть 3 или более значений в фрейме данных списка ячейке, он должен сделать 3 или более отдельные строки значений.

Вы знаете, как это сделать?


Я использую этот код, чтобы получить JSon и данных кадра:

i <- fromJSON(post.request.url) 
i <- as.data.frame(i$insights$data) 

enter image description here


Edit:

  • Не будет более глубокого гнездования, только на одном уровне.
  • Этот список не нужен в результате, мне нужны только значения и их имена.
+0

Пожалуйста, поделитесь вывод 'dput (I)' как часть вашего вопроса, а также показать, что ваш желаемый результат будет. – A5C1D2H2I1M1N2O1R2T1

+0

На самом деле, почему вы хотите сохранить столбцы значений в качестве списков в первую очередь? – A5C1D2H2I1M1N2O1R2T1

+0

Будет ли гнездование глубже, чем у вас здесь? – A5C1D2H2I1M1N2O1R2T1

ответ

1

Давайте предположим, что вы начинаете с того, что выглядит следующим образом:

mydf <- data.frame(a = c("A", "B", "C", "D"), period = "lifetime") 
mydf$values <- list(list(value = 42), list(value = 5), 
        list(value = list(like = 38, share = 11)), 
        list(value = list(like = 38, share = 13))) 

str(mydf) 
## 'data.frame': 4 obs. of 3 variables: 
## $ a  : Factor w/ 4 levels "A","B","C","D": 1 2 3 4 
## $ period: Factor w/ 1 level "lifetime": 1 1 1 1 
## $ values:List of 4 
## ..$ :List of 1 
## .. ..$ value: num 42 
## ..$ :List of 1 
## .. ..$ value: num 5 
## ..$ :List of 1 
## .. ..$ value:List of 2 
## .. .. ..$ like : num 38 
## .. .. ..$ share: num 11 
## ..$ :List of 1 
## .. ..$ value:List of 2 
## .. .. ..$ like : num 38 
## .. .. ..$ share: num 13 
## NULL 

Вместо того, чтобы сохранить списки в выходе, я бы предложил уплощение данные , возможно, используя такую ​​функцию:

myFun <- function(indt, col) { 
    if (!is.data.table(indt)) indt <- as.data.table(indt) 
    other_names <- setdiff(names(indt), col) 
    list_col <- indt[[col]] 
    rep_out <- sapply(list_col, function(x) length(unlist(x, use.names = FALSE))) 
    flat <- { 
    if (is.null(names(list_col))) names(list_col) <- seq_along(list_col) 
    setDT(tstrsplit(names(unlist(list_col)), ".", fixed = TRUE))[ 
     , val := unlist(list_col, use.names = FALSE)][] 
    } 
    cbind(indt[rep(1:nrow(indt), rep_out)][, (col) := NULL], flat) 
} 

Вот что делает с «mydf» Я поделился:

myFun(mydf, "values") 
## a period V1 V2 V3 val 
## 1: A lifetime 1 value NA 42 
## 2: B lifetime 2 value NA 5 
## 3: C lifetime 3 value like 38 
## 4: C lifetime 3 value share 11 
## 5: D lifetime 4 value like 38 
## 6: D lifetime 4 value share 13 
+0

Большое спасибо. Я не могу ввести в действие часть setDT в вашем коде. Должен быть strsplit вместо tstrsplit, я думаю, но он все еще говорит: Ошибка в setDT (strsplit (имена (unlist (list_col)), ".", Fixed = TRUE)): Все элементы в аргументе 'x' to 'setDT' должен иметь одинаковую длину Я еще не очень хорошо знаком с таблицей данных. – Larssen

+0

@Larssen, 'tstrsplit' является функцией в последних версиях« data.table »и имеет важное значение для этого ответа. – A5C1D2H2I1M1N2O1R2T1

Смежные вопросы