Разбиение списка из n элементов на один массив данных из n векторов - PullRequest
0 голосов
/ 20 июня 2019

У меня есть список, который содержит, скажем, r из 5 элементов неравной длины

R

$First
[1] "Jan"   "feb"   "March" "Ram"  

$Second
[1] "Jan"   "feb"   "April"

$Third
[1] "Jan"   "feb"   "May"   "Shyam"

$Fourth
[1] "Jan"  "feb"  "June" "abcd" "July"

$Fifth
[1] "Jan"     "feb"     "asdfgg"  "dfhfhsa" "qwer" 

Теперь я хочу преобразовать этот список в кадр данных из пяти векторов после удаления первых двух общих значений.

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

we<-r$First[3:4]

me<-r$Second[3]

er<-r$Third[3:4]

rt<-r$Fourth[3:5]

ty<-r$Fifth[3:5]

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

Вывод должен выглядеть как

   First   Second  Third   Fourth   Fifth    
1  March   April    May     June     asdfgg
2  Ram    NA        Shyam    abcd    dfhfhsa
3   NA    NA          NA      July    qwer

Ответы [ 3 ]

1 голос
/ 20 июня 2019

Мы можем сделать это за tidyverse с помощью discard, используя list элементы, имеющие intersect ing-элементы, и преобразовать неравную list длину в matrix с stri_list2matrix из stringi

library(tidyverse)
library(stringi)
map(r, ~  discard(.x, .x %in% reduce(r, intersect))) %>% 
   stri_list2matrix
#      [,1]    [,2]    [,3]    [,4]   [,5]     
#[1,] "March" "April" "May"   "June" "asdfgg" 
#[2,] "Ram"   NA      "Shyam" "abcd" "dfhfhsa"
#[3,] NA      NA      NA      "July" "qwer"   

или в одну линию без труб

stri_list2matrix(map(r, discard, `%in%`, reduce(r, intersect)))

данные

r <- list(First = c("Jan", "feb", "March", "Ram"), Second = c("Jan", 
"feb", "April"), Third = c("Jan", "feb", "May", "Shyam"), Fourth = c("Jan", 
"feb", "June", "abcd", "July"), Fifth = c("Jan", "feb", "asdfgg", 
"dfhfhsa", "qwer"))
1 голос
/ 20 июня 2019

Мы можем найти два общих значения, сначала используя Reduce, а затем удалить их из каждого элемента списка, используя sapply, и преобразовать оставшиеся элементы в кадр данных путем подстановки

common_vals <- head(Reduce(intersect, r), 2)
r1 <- sapply(r, function(x) x[!x %in% common_vals])
n <- max(lengths(r1))
data.frame(sapply(r1, `[`, 1:n))

#  First Second Third Fourth   Fifth
#1 March  April   May   June  asdfgg
#2   Ram   <NA> Shyam   abcd dfhfhsa
#3  <NA>   <NA>  <NA>   July    qwer

data

r <- list(First = c("Jan","feb","March","Ram" ), Second = c("Jan","feb","April"), 
      Third = c("Jan","feb","May" ,"Shyam"), 
      Fourth = c("Jan","feb" ,"June","abcd","July"), 
      Fifth = c("Jan","feb","asdfgg","dfhfhsa","qwer"))
0 голосов
/ 20 июня 2019

Если вы просто хотите отбросить первые два элемента каждого вектора и преобразовать в data.frame, то этого должно быть достаточно:

nmax <- max(lengths(r))
data.frame(lapply(r, "[", 3:nmax))

#   First Second Third Fourth   Fifth
# 1 March  April   May   June  asdfgg
# 2   Ram   <NA> Shyam   abcd dfhfhsa
# 3  <NA>   <NA>  <NA>   July    qwer
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...