목록을 데이터 프레임으로 변환
데이터 목록이 중첩되어 있습니다.그것의 길이는 132이고 각 항목은 길이 20의 목록입니다.이 구조를 132개의 행과 20개의 열을 가진 데이터 프레임으로 빠르게 변환할 수 있는 방법이 있습니까?
다음은 작업할 몇 가지 샘플 데이터입니다.
l <- replicate(
132,
as.list(sample(letters, 20)),
simplify = FALSE
)
와 함께rbind
do.call(rbind.data.frame, your_list)
: 반환 집편 : 이전버반환전반환data.frame
list
(@IanSudbery가 코멘트에서 지적했듯이) 벡터 대신 의 값입니다.
2020년 7월 업데이트:
변수 " " "의 입니다.stringsAsFactors
은 금은입니다.default.stringsAsFactors()
결과적으로 산출되는.FALSE
기본값으로
목록이 호출되었다고 가정합니다.l
:
df <- data.frame(matrix(unlist(l), nrow=length(l), byrow=TRUE))
위의 명령은 모든 문자 열을 요인으로 변환하며, 이를 방지하기 위해 data.frame() 호출에 매개 변수를 추가할 수 있습니다.
df <- data.frame(matrix(unlist(l), nrow=132, byrow=TRUE),stringsAsFactors=FALSE)
당신은 할 수 .plyr
를 들어, 형식의 중첩된 , 형식의 경우
l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
, b = list(var.1 = 4, var.2 = 5, var.3 = 6)
, c = list(var.1 = 7, var.2 = 8, var.3 = 9)
, d = list(var.1 = 10, var.2 = 11, var.3 = 12)
)
이제 길이가 4이고 의 각 목록이 있습니다.l
길이 3의 다른 목록이 포함되어 있습니다.이제 실행할 수 있습니다.
library (plyr)
df <- ldply (l, data.frame)
그리고 @Marek와 @nico라는 대답과 같은 결과를 얻어야 합니다.
'각 항목은 길이 20의 목록입니다'라는 원래 설명과 일치하도록 샘플 데이터를 수정합니다.
mylistlist <- replicate(
132,
as.list(sample(letters, 20)),
simplify = FALSE
)
다음과 같은 데이터 프레임으로 변환할 수 있습니다.
data.frame(t(sapply(mylistlist,c)))
sapply
행렬로 변환합니다. data.frame
행렬을 데이터 프레임으로 변환합니다.
결과:
당신의 목록이 호출되었다고 가정합니다.L
,
data.frame(Reduce(rbind, L))
키지data.table
.rbindlist
▁super▁is의 초고속 입니다.do.call(rbind, list(...))
.
의 목록을 사용할 수 있습니다.lists
,data.frames
또는data.tables
입력으로서
library(data.table)
ll <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
, b = list(var.1 = 4, var.2 = 5, var.3 = 6)
, c = list(var.1 = 7, var.2 = 8, var.3 = 9)
, d = list(var.1 = 10, var.2 = 11, var.3 = 12)
)
DT <- rbindlist(ll)
이는 다음을 반환합니다.data.table
는 에상됨속서의 상속을 받습니다.data.frame
.
data.frame으로 다시 변환하려면as.data.frame(DT)
그tibble
에는 패지에기있습다니능이 이 있습니다.enframe()
강제로 중첩시킴으로써 이 문제를 해결합니다.list
: 된 개체tibble
("데이터 프레임") 개체입니다.R for Data Science의 간단한 예는 다음과 같습니다.
x <- list(
a = 1:5,
b = 3:4,
c = 5:6
)
df <- enframe(x)
df
#> # A tibble: 3 × 2
#> name value
#> <chr> <list>
#> 1 a <int [5]>
#> 2 b <int [2]>
#> 3 c <int [2]>
목록에 에, 당의목록여개둥있의때기문에지가러에신▁in,▁since때에,l
은 수있다니습사를 할 수 .unlist(recursive = FALSE)
에 에 합니다.enframe()
사용합니다tidyr::unnest()
개의 열( " " " " " (으)로 의 열)이 있는 "" .name
는 입니다.value
)을 사용하여 할 수 add_column()
값의 순서를 132번 반복합니다. 그냥 ㅠㅠㅠㅠspread()
가치관
library(tidyverse)
l <- replicate(
132,
list(sample(letters, 20)),
simplify = FALSE
)
l_tib <- l %>%
unlist(recursive = FALSE) %>%
enframe() %>%
unnest()
l_tib
#> # A tibble: 2,640 x 2
#> name value
#> <int> <chr>
#> 1 1 d
#> 2 1 z
#> 3 1 l
#> 4 1 b
#> 5 1 i
#> 6 1 j
#> 7 1 g
#> 8 1 w
#> 9 1 r
#> 10 1 p
#> # ... with 2,630 more rows
l_tib_spread <- l_tib %>%
add_column(index = rep(1:20, 132)) %>%
spread(key = index, value = value)
l_tib_spread
#> # A tibble: 132 x 21
#> name `1` `2` `3` `4` `5` `6` `7` `8` `9` `10` `11`
#> * <int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 1 d z l b i j g w r p y
#> 2 2 w s h r i k d u a f j
#> 3 3 r v q s m u j p f a i
#> 4 4 o y x n p i f m h l t
#> 5 5 p w v d k a l r j q n
#> 6 6 i k w o c n m b v e q
#> 7 7 c d m i u o e z v g p
#> 8 8 f s e o p n k x c z h
#> 9 9 d g o h x i c y t f j
#> 10 10 y r f k d o b u i x s
#> # ... with 122 more rows, and 9 more variables: `12` <chr>, `13` <chr>,
#> # `14` <chr>, `15` <chr>, `16` <chr>, `17` <chr>, `18` <chr>,
#> # `19` <chr>, `20` <chr>
▁some▁are있다▁depending습니▁there가가▁lists지▁on▁of가 있습니다.tidyverse
동일하지 않은 길이 목록에서 잘 작동하는 옵션:
l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
, b = list(var.1 = 4, var.2 = 5)
, c = list(var.1 = 7, var.3 = 9)
, d = list(var.1 = 10, var.2 = 11, var.3 = NA))
df <- dplyr::bind_rows(l)
df <- purrr::map_df(l, dplyr::bind_rows)
df <- purrr::map_df(l, ~.x)
# all create the same data frame:
# A tibble: 4 x 3
var.1 var.2 var.3
<dbl> <dbl> <dbl>
1 1 2 3
2 4 5 NA
3 7 NA 9
4 10 11 NA
벡터와 데이터 프레임을 혼합할 수도 있습니다.
library(dplyr)
bind_rows(
list(a = 1, b = 2),
data_frame(a = 3:4, b = 5:6),
c(a = 7)
)
# A tibble: 4 x 2
a b
<dbl> <dbl>
1 1 2
2 3 5
3 4 6
4 7 NA
이 메서드는 다음을 사용합니다.tidyverse
꾸러미(퍼러)
목록:
x <- as.list(mtcars)
데이터 프레임으로 변환(a)tibble
보다 구체적으로):
library(purrr)
map_df(x, ~.x)
편집: 2021년 5월 30일
이는 실제로 다음을 통해 달성할 수 있습니다.bind_rows()
에서 기능하는.dplyr
.
x <- as.list(mtcars)
dplyr::bind_rows(x)
A tibble: 32 x 11
mpg cyl disp hp drat wt qsec vs am gear carb
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 21 6 160 110 3.9 2.62 16.5 0 1 4 4
2 21 6 160 110 3.9 2.88 17.0 0 1 4 4
3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1
4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
# ... with 22 more rows
Reshape2는 위의 플라이어 예제와 동일한 출력을 생성합니다.
library(reshape2)
l <- list(a = list(var.1 = 1, var.2 = 2, var.3 = 3)
, b = list(var.1 = 4, var.2 = 5, var.3 = 6)
, c = list(var.1 = 7, var.2 = 8, var.3 = 9)
, d = list(var.1 = 10, var.2 = 11, var.3 = 12)
)
l <- melt(l)
dcast(l, L1 ~ L2)
산출량:
L1 var.1 var.2 var.3
1 a 1 2 3
2 b 4 5 6
3 c 7 8 9
4 d 10 11 12
픽셀이 거의 다 떨어져 있는 경우 이 모든 작업을 한 줄에서 재캐스트()로 수행할 수 있습니다.
@Marek의 답변 확장: 문자열이 요인으로 전환되는 것을 피하고 싶다면 효율성은 걱정할 필요가 없습니다.
do.call(rbind, lapply(your_list, data.frame, stringsAsFactors=FALSE))
중첩된 JSON에서 얻은 수준과 같은 수준이 3개 이상인 심층 중첩 리스트의 일반적인 경우:
{
"2015": {
"spain": {"population": 43, "GNP": 9},
"sweden": {"population": 7, "GNP": 6}},
"2016": {
"spain": {"population": 45, "GNP": 10},
"sweden": {"population": 9, "GNP": 8}}
}
의 접근을 고려합니다.melt()
먼저 중첩된 목록을 큰 형식으로 변환하려면 다음과 같이 하십시오.
myjson <- jsonlite:fromJSON(file("test.json"))
tall <- reshape2::melt(myjson)[, c("L1", "L2", "L3", "value")]
L1 L2 L3 value
1 2015 spain population 43
2 2015 spain GNP 9
3 2015 sweden population 7
4 2015 sweden GNP 6
5 2016 spain population 45
6 2016 spain GNP 10
7 2016 sweden population 9
8 2016 sweden GNP 8
다음에dcast()
그런 다음 각 변수가 열을 형성하고 각 관측치가 행을 형성하는 정돈된 데이터 집합으로 다시 폭을 넓힙니다.
wide <- reshape2::dcast(tall, L1+L2~L3)
# left side of the formula defines the rows/observations and the
# right side defines the variables/measurements
L1 L2 GNP population
1 2015 spain 9 43
2 2015 sweden 6 7
3 2016 spain 10 45
4 2016 sweden 8 9
이 질문에 대한 답변에 타이밍과 함께 더 많은 답변이 질문에 대한 답변:목록을 데이터 프레임으로 캐스팅하는 가장 효율적인 방법은 무엇입니까?
열에 대한 벡터가 아닌 목록이 있는 데이터 프레임을 생성하지 않는 가장 빠른 방법은 (Martin Morgan의 답변에서) 다음과 같습니다.
l <- list(list(col1="a",col2=1),list(col1="b",col2=2))
f = function(x) function(i) unlist(lapply(x, `[[`, i), use.names=FALSE)
as.data.frame(Map(f(l), names(l[[1]])))
다음과 같은 간단한 명령이 저에게 효과가 있었습니다.
myDf <- as.data.frame(myList)
참조(쿼리 답변)
> myList <- list(a = c(1, 2, 3), b = c(4, 5, 6))
> myList
$a
[1] 1 2 3
$b
[1] 4 5 6
> myDf <- as.data.frame(myList)
a b
1 1 4
2 2 5
3 3 6
> class(myDf)
[1] "data.frame"
그러나 목록을 데이터 프레임으로 변환하는 방법이 명확하지 않으면 실패합니다.
> myList <- list(a = c(1, 2, 3), b = c(4, 5, 6, 7))
> myDf <- as.data.frame(myList)
(함수(..., row.names = NULL, check.rows = FALSE, check.names = TRUE, : 인수는 서로 다른 행 수를 암시합니다: 3, 4)
참고: 답변은 질문의 제목을 향하며 질문의 일부 세부 정보를 건너뛸 수 있습니다.
목록에 동일한 차원의 요소가 있는 경우bind_rows
정숙한 역에서 기능합니다.
# Load the tidyverse
Library(tidyverse)
# make a list with elements having same dimensions
My_list <- list(a = c(1, 4, 5), b = c(9, 3, 8))
## Bind the rows
My_list %>% bind_rows()
결과는 두 개의 행이 있는 데이터 프레임입니다.
데이터가 같은 길이의 벡터 리스트일 수도 있습니다.
lolov = list(list(c(1,2,3),c(4,5,6)), list(c(7,8,9),c(10,11,12),c(13,14,15)) )
(내부 벡터는 목록일 수도 있지만 읽기 쉽도록 단순화합니다.)
그러면 당신은 다음과 같이 수정할 수 있습니다.한 번에 하나의 수준을 나열 취소할 수 있습니다.
lov = unlist(lolov, recursive = FALSE )
> lov
[[1]]
[1] 1 2 3
[[2]]
[1] 4 5 6
[[3]]
[1] 7 8 9
[[4]]
[1] 10 11 12
[[5]]
[1] 13 14 15
이제 다른 답변에 언급된 원하는 방법을 사용합니다.
library(plyr)
>ldply(lov)
V1 V2 V3
1 1 2 3
2 4 5 6
3 7 8 9
4 10 11 12
5 13 14 15
이것이 마침내 저에게 효과가 있었던 것입니다.
do.call("rbind", lapply(S1, as.data.frame))
병렬(멀티코어, 멀티세션 등) 솔루션의 경우 다음을 사용합니다.purrr
솔루션 제품군, 사용:
library (furrr)
plan(multisession) # see below to see which other plan() is the more efficient
myTibble <- future_map_dfc(l, ~.x)
어디에l
목록입니다.
효율적인 가장효벤크마를 하기 위해plan()
사용할 수 있는 항목:
library(tictoc)
plan(sequential) # reference time
# plan(multisession) # benchamark plan() goes here. See ?plan().
tic()
myTibble <- future_map_dfc(l, ~.x)
toc()
데이터 프레임은 동일한 길이의 벡터 목록일 뿐이므로 이를 위한 짧은 방법(가장 빠른 방법은 아닐 수도 있음)은 기본값을 사용하는 것입니다.따라서 입력 목록과 30 x 132 data.frame 간의 변환은 다음과 같습니다.
df <- data.frame(l)
여기서 132 x 30 행렬로 전환하고 데이터 프레임으로 다시 변환할 수 있습니다.
new_df <- data.frame(t(df))
하나의 라이너로서:
new_df <- data.frame(t(data.frame(l)))
행 이름은 보기에 꽤 성가시겠지만 항상 이름을 바꿀 수 있습니다.
rownames(new_df) <- 1:nrow(new_df)
l <- replicate(10,list(sample(letters, 20)))
a <-lapply(l[1:10],data.frame)
do.call("cbind", a)
내가 찾은 모든 해결책은 모든 객체에 적용되는 것처럼 보입니다.list
같은 것을 가지다length
변환이 필요했습니다.list
data.frame
length
물의체에 있는 의.list
불평등한length
는 베이스 아는베입니다스이래▁base입니다.R
내가 생각해 낸 해결책.그것이 매우 비효율적이라는 것은 의심의 여지가 없지만, 효과가 있는 것처럼 보입니다.
x1 <- c(2, 13)
x2 <- c(2, 4, 6, 9, 11, 13)
x3 <- c(1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13)
my.results <- list(x1, x2, x3)
# identify length of each list
my.lengths <- unlist(lapply(my.results, function (x) { length(unlist(x))}))
my.lengths
#[1] 2 6 20
# create a vector of values in all lists
my.values <- as.numeric(unlist(c(do.call(rbind, lapply(my.results, as.data.frame)))))
my.values
#[1] 2 13 2 4 6 9 11 13 1 1 2 3 3 4 5 5 6 7 7 8 9 9 10 11 11 12 13 13
my.matrix <- matrix(NA, nrow = max(my.lengths), ncol = length(my.lengths))
my.cumsum <- cumsum(my.lengths)
mm <- 1
for(i in 1:length(my.lengths)) {
my.matrix[1:my.lengths[i],i] <- my.values[mm:my.cumsum[i]]
mm <- my.cumsum[i]+1
}
my.df <- as.data.frame(my.matrix)
my.df
# V1 V2 V3
#1 2 2 1
#2 13 4 1
#3 NA 6 2
#4 NA 9 3
#5 NA 11 3
#6 NA 13 4
#7 NA NA 5
#8 NA NA 5
#9 NA NA 6
#10 NA NA 7
#11 NA NA 7
#12 NA NA 8
#13 NA NA 9
#14 NA NA 9
#15 NA NA 10
#16 NA NA 11
#17 NA NA 11
#18 NA NA 12
#19 NA NA 13
#20 NA NA 13
를 사용하는 것은 어떻습니까?map_
함께 합니다.for
: 프루? 내 해결책은 다음과 같습니다.
list_to_df <- function(list_to_convert) {
tmp_data_frame <- data.frame()
for (i in 1:length(list_to_convert)) {
tmp <- map_dfr(list_to_convert[[i]], data.frame)
tmp_data_frame <- rbind(tmp_data_frame, tmp)
}
return(tmp_data_frame)
}
map_dfr
data.frame으로 변환합니다.rbind
그들을 완전히 결합시킵니다.
당신의 경우는 다음과 같습니다.
converted_list <- list_to_df(l)
ㅠㅠcollapse::unlist2d
' 해제'의 경우 ('data.frame'은 다음과 같습니다.)
l <- replicate(
132,
list(sample(letters, 20)),
simplify = FALSE
)
library(collapse)
head(unlist2d(l))
.id.1 .id.2 V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
1 1 1 e x b d s p a c k z q m u l h n r t o y
2 2 1 r t i k m b h n s e p f o c x l g v a j
3 3 1 t r v z a u c o w f m b d g p q y e n k
4 4 1 x i e p f d q k h b j s z a t v y l m n
5 5 1 d z k y a p b h c v f m u l n q e i w j
6 6 1 l f s u o v p z q e r c h n a t m k y x
head(unlist2d(l, idcols = FALSE))
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14 V15 V16 V17 V18 V19 V20
1 e x b d s p a c k z q m u l h n r t o y
2 r t i k m b h n s e p f o c x l g v a j
3 t r v z a u c o w f m b d g p q y e n k
4 x i e p f d q k h b j s z a t v y l m n
5 d z k y a p b h c v f m u l n q e i w j
6 l f s u o v p z q e r c h n a t m k y x
또는 경골 패키지를 사용할 수 있습니다(정글 버전에서).
#create examplelist
l <- replicate(
132,
as.list(sample(letters, 20)),
simplify = FALSE
)
#package tidyverse
library(tidyverse)
#make a dataframe (or use as_tibble)
df <- as_data_frame(l,.name_repair = "unique")
저는 이 해결책도 제안하고 싶습니다.다른 솔루션과 비슷해 보이지만 rbind를 사용합니다.플라이어 패키지에서 충전합니다.이는 리스트에 결측 열 또는 NA 값이 있는 경우에 유용합니다.
l <- replicate(10,as.list(sample(letters,10)),simplify = FALSE)
res<-data.frame()
for (i in 1:length(l))
res<-plyr::rbind.fill(res,data.frame(t(unlist(l[i]))))
res
다른 관점에서;
install.packages("smotefamily")
library(smotefamily)
library(dplyr)
data_example = sample_generator(5000,ratio = 0.80)
genData = BLSMOTE(data_example[,-3],data_example[,3])
#There are many lists in genData. If we want to convert one of them to dataframe.
sentetic=as.data.frame.array(genData$syn_data)
# as.data.frame.array seems to be working.
언급URL : https://stackoverflow.com/questions/4227223/convert-a-list-to-a-data-frame
'source' 카테고리의 다른 글
Azure에 대한 Windows 서비스? (0) | 2023.05.17 |
---|---|
SQL Server 2008의 데이터베이스에서 데이터를 사용하여 단일 테이블 백업 (0) | 2023.05.17 |
베어 저장소와 비베어 저장소의 실질적인 차이점은 무엇입니까? (0) | 2023.05.17 |
CreatedAtRoute()에 대해 설명할 수 있는 사람이 있습니까? (0) | 2023.05.17 |
필요하지 않은 렌더 섹션이 있는지 어떻게 알 수 있습니까? (0) | 2023.05.17 |