San*_*nti 5 r multiple-columns
我有一个数据表,其中最后一列是列表的一列。下面是它的外观:
Col1 | Col2 | ListCol
--------------------------
na | na | [obj1, obj2]
na | na | [obj1, obj2]
na | na | [obj1, obj2]
Run Code Online (Sandbox Code Playgroud)
我想要的是
Col1 | Col2 | Col3 | Col4
--------------------------
na | na | obj1 | obj2
na | na | obj1 | obj2
na | na | obj1 | obj2
Run Code Online (Sandbox Code Playgroud)
我知道所有列表都有相同数量的元素。
编辑:
ListCol中的每个元素都是一个包含两个元素的列表。
目前,tidyverse 的答案是:
library(dplyr)
library(tidyr)
data %>% unnest_wider(ListCol)
Run Code Online (Sandbox Code Playgroud)
这是一种方法,使用unnest和tidyr::spread...
library(dplyr)
library(tidyr)
#example df
df <- tibble(a=c(1, 2, 3), b=list(c(2, 3), c(4, 5), c(6, 7)))
df %>% unnest(b) %>%
group_by(a) %>%
mutate(col=seq_along(a)) %>% #add a column indicator
spread(key=col, value=b)
a `1` `2`
<dbl> <dbl> <dbl>
1 1. 2. 3.
2 2. 4. 5.
3 3. 6. 7.
Run Code Online (Sandbox Code Playgroud)
此线程中有两个很棒的单衬建议:
cbind(df[1], t(data.frame(df$b)))这是@Onyambu使用base R 的结果。为了得到这个答案,我们需要知道 adataframe是一个列表,并且需要一点创造力。
df %>% unnest_wider(b)这是@iago使用tidyverse. 您需要额外的包并了解所有nest动词,但人们可以认为它更具可读性。
library(dplyr)
library(tidyr)
library(purrr)
library(microbenchmark)
N <- 100
df <- tibble(a = 1:N, b = map2(1:N, 1:N, c))
tidy_foo <- function() suppressMessages(df %>% unnest_wider(b))
base_foo <- function() cbind(df[1],t(data.frame(df$b))) %>% as_tibble # To be fair
microbenchmark(tidy_foo(), base_foo())
Run Code Online (Sandbox Code Playgroud)
Unit: milliseconds
expr min lq mean median uq max neval
tidy_foo() 102.4388 108.27655 111.99571 109.39410 113.1377 194.2122 100
base_foo() 4.5048 4.71365 5.41841 4.92275 5.2519 13.1042 100
Run Code Online (Sandbox Code Playgroud)
base R解决方案快 20 倍。