Конвертировать кадр данных R в список векторов - PullRequest
0 голосов
/ 19 марта 2019

У меня есть фрейм данных (импортированный из листа Excel, где я написал список строк строка за строкой) и хочу преобразовать строки в список векторов, где каждый вектор содержит значения пропущенных ячеек для этой строки :

например:

#Sample data frame
dfX <- data.frame(C0 = c(1,2,3),
              C1 = c("Apple","Apple","Pear"),
              C2 = c("Banana","Orange", "Lemon"),
              C3 = c("Pear","Melon", ""))

Что будет использовано для создания следующего списка:

myList = list(c("Apple","Banana", "Pear"),
          c("Apple","Orange", "Melon"),
          c("Pear","Lemon"))

Обратите внимание, что третий вектор усекается до двух элементов, поскольку ячейка содержит пустую строку. Также обратите внимание, что индекс (C0) упал.

Я видел несколько примеров, которые преобразуют фрейм данных в матрицу и используют функцию разделения для вставки результатов в глобальную среду, например,

list2env(setNames(split(as.matrix(dfX),
                    row(dfX)), paste0("Row",1:3)),
                    envir=.GlobalEnv)

Но мне было интересно, есть ли (а) более новая функция tidyverse для обработки этого и (б) способ заполнить список прямо (позже я хочу применить функцию к этому списку). Также, если возможно, захотите обработать пропущенные значения по пути в список!

Ответы [ 2 ]

2 голосов
/ 19 марта 2019

Как вас интересует способ tidyverse, один из вариантов будет

library(tidyverse)

dfX %>%
  group_split(C0) %>% #Or use split(.$C0) if `dplyr` is not updated
  map(~discard(flatten_chr(.), . == "")[-1])

#[[1]]
#[1] "Apple"  "Banana" "Pear"  

#[[2]]
#[1] "Apple"  "Orange" "Melon" 

#[[3]]
#[1] "Pear"  "Lemon"

group_split доступен в dplyr 0.8.0.Также это предполагает, что у вас будет уникальный C0 в каждой строке, и для каждой строки мы discard будем иметь любое значение, равное пустым строкам ("").


Или в базовой комбинации Rsplit и lapply также будут работать.

lapply(split(dfX[-1], dfX$C0), function(x) x[x != ""])

#$`1`
#[1] "Apple"  "Banana" "Pear"  

#$`2`
#[1] "Apple"  "Orange" "Melon" 

#$`3`
#[1] "Pear"  "Lemon"

Другая базовая опция R - apply с MARGIN = 1

apply(dfX[-1], 1, function(x) x[x!= ""])
1 голос
/ 19 марта 2019

Базовая опция R: by

by(dfX, dfX$C0, function(x) unlist(x[x != ''][-1]))
#dfX$C0: 1
#[1] "Apple"  "Banana" "Pear"
#------------------------------------------------------------
#dfX$C0: 2
#[1] "Apple"  "Orange" "Melon"
#------------------------------------------------------------
#dfX$C0: 3
#[1] "Pear"  "Lemon"

by возвращает «одетый» список, игнорируя атрибуты, которые соответствуют ожидаемым myList.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...