IT story

데이터 프레임 목록을 만들려면 어떻게합니까?

hot-time 2020. 5. 27. 07:41
반응형

데이터 프레임 목록을 만들려면 어떻게합니까?


데이터 프레임 목록을 작성하는 방법과 목록에서 해당 데이터 프레임 각각에 액세스하는 방법은 무엇입니까?

예를 들어, 이러한 데이터 프레임을 어떻게 목록에 넣을 수 있습니까?

d1 <- data.frame(y1 = c(1, 2, 3),
                 y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1),
                 y2 = c(6, 5, 4))

이것은 귀하의 질문과 관련이 없지만 함수 호출 내에서 사용 =하고 싶지 않습니다 <-. 를 사용 하면 작업 환경 환경에서 <-변수를 만들 수 있습니다.y1y2

d1 <- data.frame(y1 <- c(1, 2, 3), y2 <- c(4, 5, 6))
y1
# [1] 1 2 3
y2
# [1] 4 5 6

이것은 데이터 프레임에서 열 이름을 만들 때 원하는 것처럼 보이지 않습니다.

d1
#   y1....c.1..2..3. y2....c.4..5..6.
# 1                1                4
# 2                2                5
# 3                3                6

반면에 =연산자는 벡터를 인수와 연관시킵니다 data.frame.

귀하의 질문에 관해서는, 데이터 프레임 목록을 만드는 것이 쉽습니다.

d1 <- data.frame(y1 = c(1, 2, 3), y2 = c(4, 5, 6))
d2 <- data.frame(y1 = c(3, 2, 1), y2 = c(6, 5, 4))
my.list <- list(d1, d2)

다른 목록 요소에 액세스하는 것처럼 데이터 프레임에 액세스합니다.

my.list[[1]]
#   y1 y2
# 1  1  4
# 2  2  5
# 3  3  6

다른 답변을 보여 어떻게 당신이 때 data.frames의 목록을 만들기 위해 이미 예를 들어, data.frames의 무리 d1, d2.... 문제가 순차적으로 명명 된 데이터 프레임을 갖는, 그리고 목록에 넣어 것은입니다 좋은 수정이지만 가장 좋은 방법은 처음 에는 목록없는 많은 데이터 프레임을 사용하지 않는 것입니다 .

다른 답변은 요소를 나열하고 액세스하는 데 데이터 프레임을 할당하는 방법에 대한 자세한 정보를 제공합니다. 여기에서도 조금 다룰 것입니다. 그러나 요점많은 것을 가질 때까지 기다리지 말아야 한다는 것 입니다. data.frames목록에 추가하십시오. 목록부터 시작하십시오.

이 답변의 나머지 부분에서는 순차 변수를 만들고 싶은 유혹에 빠질 수있는 몇 가지 일반적인 경우를 다루고 목록으로 바로 이동하는 방법을 보여줍니다. R의 목록을 처음 사용하는 경우 목록 요소 [[[액세스 요소의 차이점은 무엇입니까? 를 읽어보십시오 . .


처음부터 목록

처음 d1 d2 d3에는 ...을 만들지 마십시오 dn. 요소 가 포함 된 목록 d만듭니다 n.

여러 파일을 데이터 프레임 목록으로 읽기

이것은 파일을 읽을 때 매우 쉽게 수행됩니다. data1.csv, data2.csv, ...디렉토리에 파일 이있을 수 있습니다. 목표는이라는 data.frames 목록입니다 mydata. 가장 먼저 필요한 것은 모든 파일 이름을 가진 벡터입니다. 붙여 넣기 (예 :)로이를 구성 할 수 my_files = paste0("data", 1:5, ".csv")있지만 list.files적절한 모든 파일을 가져 오는 데 사용 하는 것이 더 쉽습니다 my_files <- list.files(pattern = "\\.csv$"). 정규식을 사용하여 파일을 일치시킬 수 있으며, 도움이 필요한 경우 다른 질문에서 정규식에 대해 자세히 읽어보십시오. 이 방법을 사용하면 멋진 이름 지정 체계를 따르지 않아도 모든 CSV 파일을 가져올 수 있습니다. 또는 여러 CSV 파일에서 특정 CSV 파일을 선택해야하는 경우 더 멋진 정규식 패턴을 사용할 수 있습니다.

이 시점에서 대부분의 R 초보자는 for루프 를 사용하며 아무런 문제가 없으며 정상적으로 작동합니다.

my_data <- list()
for (i in seq_along(my_files)) {
    my_data[[i]] <- read.csv(file = my_files[i])
}

방법은 그것을 할 더-같은 R은 함께 lapply위의 바로 가기 인

my_data <- lapply(my_files, read.csv)

물론 다른 데이터 가져 오기 기능을 read.csv적절하게 대체하십시오 . readr::read_csv또는 data.table::fread더 빠른 것, 또는 당신은 또한 다른 파일 형식에 대해 다른 기능을해야 할 수도 있습니다.

어느 쪽이든, 파일과 일치하도록 목록 요소의 이름을 지정하는 것이 편리합니다.

names(my_data) <- gsub("\\.csv$", "", my_files)
# or, if you prefer the consistent syntax of stringr
names(my_data) <- stringr::str_replace(my_files, pattern = ".csv", replacement = "")

데이터 프레임을 데이터 프레임 목록으로 분할

이것은 매우 쉬우 며 기본 기능 split()은 당신을 위해 그것을합니다. 데이터의 열 (또는 열) 또는 원하는 다른 항목으로 분할 할 수 있습니다.

mt_list = split(mtcars, f = mtcars$cyl)
# This gives a list of three data frames, one for each value of cyl

또한 교차 검증을 위해 데이터 프레임을 여러 조각으로 나눌 수있는 좋은 방법입니다. mtcars교육, 테스트 및 유효성 검사 로 나눌 수 있습니다 .

groups = sample(c("train", "test", "validate"),
                size = nrow(mtcars), replace = TRUE)
mt_split = split(mtcars, f = groups)
# and mt_split has appropriate names already!

데이터 프레임 목록 시뮬레이션

아마도 당신은 다음과 같은 데이터를 시뮬레이션하고있을 것입니다 :

my_sim_data = data.frame(x = rnorm(50), y = rnorm(50))

그러나 누가 하나의 시뮬레이션 만합니까? 이 작업을 100 번, 1000 번 이상으로하고 싶습니다! 그러나 작업 공간에 10,000 개의 데이터 프레임을 원하지 않습니다 . 사용 replicate및 목록에 넣어 :

sim_list = replicate(n = 10,
                     expr = {data.frame(x = rnorm(50), y = rnorm(50))},
                     simplify = F)

이 경우 특히 별도의 데이터 프레임이 필요한지 또는 "그룹"열이있는 단일 데이터 프레임이 제대로 작동하는지 고려해야합니다. 사용 data.table하거나 dplyr데이터 그룹에 "그룹 별"작업을 수행하는 것은 매우 쉽습니다.

데이터를 목록에 넣지 않았습니다. (다음에 다시하겠습니다.하지만 지금 무엇을 할 수 있습니까?

그것들이 이상한 구색이라면 (비정상적 임), 간단히 그것들을 할당 할 수 있습니다 :

mylist <- list()
mylist[[1]] <- mtcars
mylist[[2]] <- data.frame(a = rnorm(50), b = runif(50))
...

당신이 패턴에 이름이 데이터 프레임이있는 경우 예를 들어, df1, df2, df3, 그리고 당신은 목록에 원하는 작업을 수행 할 수 있습니다 get당신은 이름과 일치하는 정규 표현식을 쓸 수 있는지를. 같은 것

df_list = mget(ls(pattern = "df[0-9]"))
# this would match any object with "df" followed by a digit in its name
# you can test what objects will be got by just running the
ls(pattern = "df[0-9]")
# part and adjusting the pattern until it gets the right objects.

일반적으로 mget여러 객체를 가져 와서 명명 된 목록으로 반환하는 데 사용됩니다. 해당 get객체는 단일 객체를 가져 와서 반환합니다 (목록이 아님).

데이터 프레임 목록을 단일 데이터 프레임으로 결합

일반적인 작업은 데이터 프레임 목록을 하나의 큰 데이터 프레임으로 결합하는 것입니다. 서로 겹쳐서 쌓으려면 rbind한 쌍으로 사용 하지만 데이터 프레임 목록에는 다음 세 가지 중에서 선택할 수 있습니다.

# base option - slower but not extra dependencies
big_data = do.call(what = rbind, args = df_list)

# data table and dplyr have nice functions for this that
#  - are much faster
#  - add id columns to identify the source
#  - fill in missing values if some data frames have more columns than others
# see their help pages for details
big_data = data.table::rbindlist(df_list)
big_data = dplyr::bind_rows(df_list)

( cbind또는 dplyr::bind_cols열과 유사하게 사용 )

데이터 프레임 목록을 병합 (결합)하려면 다음 답변을 볼 수 있습니다 . 종종 아이디어는 Reduce함께 사용하기 위해 merge(또는 다른 결합 기능) 사용하는 것입니다.

왜 데이터를 목록에 넣습니까?

각 데이터 프레임에 비슷한 일을하고 싶어하고, 기능을 좋아하기 때문에 목록에 유사한 데이터를 넣고 lapply, sapply do.call, 패키지 및 기존 기능은 쉽게 그렇게 할 수 있습니다. 목록으로 쉽게 일을하는 사람들의 예는 너무나도 많습니다.purrrplyr l*ply

낮은 for 루프를 사용하더라도 변수 이름을 사용 paste하여을 사용하여 객체에 액세스하는 것보다 목록의 요소를 반복하는 것이 훨씬 쉽습니다 get. 디버그도 더 쉽습니다.

확장 성을 생각하십시오 . 당신이 정말로 단지 세 개의 변수, 사용에 그것의 벌금을해야하는 경우 d1, d2, d3. 그러나 실제로 6이 필요하다는 것이 밝혀지면 훨씬 더 타이핑됩니다. 그리고 다음에 10 또는 20이 필요할 때 코드 줄을 복사하여 붙여 넣는 것을 발견하고 찾기 / 바꾸기를 사용하여로 변경 d14하면 이것이 프로그래밍 방식이 아니라고d15 생각 합니다 . 당신이 목록을 사용하는 경우 3 예 (30) 케이스, 및 3백가지 경우의 차이는 대부분의 코드 한 줄에서입니다 --- 전혀 변화의 경우 전화 번호가 자동으로 감지되면, 얼마나 많은 예 .csv에서 파일이 없습니다 당신의 예배 규칙서.

숫자 인덱스 이외의 것을 사용하여 데이터 프레임에 액세스하려는 경우 목록의 요소 이름을 지정할 수 있습니다 (둘 다 사용할 수 있으며 XOR 선택이 아님).

전반적으로 목록을 사용하면 더 깔끔하고 읽기 쉬운 코드를 작성하게되어 버그가 줄어들고 혼동이 줄어 듭니다.


또한 각 목록 요소의 특정 컬럼과 값에 액세스 할 수 있습니다 [[[. 다음은 몇 가지 예입니다. 먼저, 목록에서 각 데이터 프레임의 첫 번째 열에 만 액세스 할 수 있습니다 . lapply(ldf, "[", 1)여기서 1열 번호를 나타냅니다.

ldf <- list(d1 = d1, d2 = d2)  ## create a named list of your data frames
lapply(ldf, "[", 1)
# $d1
#   y1
# 1  1
# 2  2
# 3  3
#
# $d2
#   y1
# 1  3
# 2  2
# 3  1

마찬가지로 두 번째 열의 첫 번째 값에 액세스 할 수 있습니다.

lapply(ldf, "[", 1, 2)
# $d1
# [1] 4
# 
# $d2
# [1] 6

그런 다음 벡터로 열 값에 직접 액세스 할 수도 있습니다. [[

lapply(ldf, "[[", 1)
# $d1
# [1] 1 2 3
#
# $d2
# [1] 3 2 1

순차적으로 명명 된 데이터 프레임이 많은 경우 다음과 같이 원하는 데이터 프레임 하위 집합의 목록을 만들 수 있습니다.

d1 <- data.frame(y1=c(1,2,3), y2=c(4,5,6))
d2 <- data.frame(y1=c(3,2,1), y2=c(6,5,4))
d3 <- data.frame(y1=c(6,5,4), y2=c(3,2,1))
d4 <- data.frame(y1=c(9,9,9), y2=c(8,8,8))

my.list <- list(d1, d2, d3, d4)
my.list

my.list2 <- lapply(paste('d', seq(2,4,1), sep=''), get)
my.list2

where my.list2 returns a list containing the 2nd, 3rd and 4th data frames.

[[1]]
  y1 y2
1  3  6
2  2  5
3  1  4

[[2]]
  y1 y2
1  6  3
2  5  2
3  4  1

[[3]]
  y1 y2
1  9  8
2  9  8
3  9  8

Note, however, that the data frames in the above list are no longer named. If you want to create a list containing a subset of data frames and want to preserve their names you can try this:

list.function <-  function() { 

     d1 <- data.frame(y1=c(1,2,3), y2=c(4,5,6))
     d2 <- data.frame(y1=c(3,2,1), y2=c(6,5,4))
     d3 <- data.frame(y1=c(6,5,4), y2=c(3,2,1))
     d4 <- data.frame(y1=c(9,9,9), y2=c(8,8,8))

     sapply(paste('d', seq(2,4,1), sep=''), get, environment(), simplify = FALSE) 
} 

my.list3 <- list.function()
my.list3

which returns:

> my.list3
$d2
  y1 y2
1  3  6
2  2  5
3  1  4

$d3
  y1 y2
1  6  3
2  5  2
3  4  1

$d4
  y1 y2
1  9  8
2  9  8
3  9  8

> str(my.list3)
List of 3
 $ d2:'data.frame':     3 obs. of  2 variables:
  ..$ y1: num [1:3] 3 2 1
  ..$ y2: num [1:3] 6 5 4
 $ d3:'data.frame':     3 obs. of  2 variables:
  ..$ y1: num [1:3] 6 5 4
  ..$ y2: num [1:3] 3 2 1
 $ d4:'data.frame':     3 obs. of  2 variables:
  ..$ y1: num [1:3] 9 9 9
  ..$ y2: num [1:3] 8 8 8

> my.list3[[1]]
  y1 y2
1  3  6
2  2  5
3  1  4

> my.list3$d4
  y1 y2
1  9  8
2  9  8
3  9  8

Taking as a given you have a "large" number of data.frames with similar names (here d# where # is some positive integer), the following is a slight improvement of @mark-miller's method. It is more terse and returns a named list of data.frames, where each name in the list is the name of the corresponding original data.frame.

The key is using mget together with ls. If the data frames d1 and d2 provided in the question were the only objects with names d# in the environment, then

my.list <- mget(ls(pattern="^d[0-9]+"))

which would return

my.list
$d1
  y1 y2
1  1  4
2  2  5
3  3  6

$d2
  y1 y2
1  3  6
2  2  5
3  1  4

This method takes advantage of the pattern argument in ls, which allows us to use regular expressions to do a finer parsing of the names of objects in the environment. An alternative to the regex "^d[0-9]+$" is "^d\\d+$".

As @gregor points out, it is a better overall to set up your data construction process so that the data.frames are put into named lists at the start.

data

d1 <- data.frame(y1 = c(1,2,3),y2 = c(4,5,6))
d2 <- data.frame(y1 = c(3,2,1),y2 = c(6,5,4))

This may be a little late but going back to your example I thought I would extend the answer just a tad.

 D1 <- data.frame(Y1=c(1,2,3), Y2=c(4,5,6))
 D2 <- data.frame(Y1=c(3,2,1), Y2=c(6,5,4))
 D3 <- data.frame(Y1=c(6,5,4), Y2=c(3,2,1))
 D4 <- data.frame(Y1=c(9,9,9), Y2=c(8,8,8))

Then you make your list easily:

mylist <- list(D1,D2,D3,D4)

Now you have a list but instead of accessing the list the old way such as

mylist[[1]] # to access 'd1'

you can use this function to obtain & assign the dataframe of your choice.

GETDF_FROMLIST <- function(DF_LIST, ITEM_LOC){
   DF_SELECTED <- DF_LIST[[ITEM_LOC]]
   return(DF_SELECTED)
}

Now get the one you want.

D1 <- GETDF_FROMLIST(mylist, 1)
D2 <- GETDF_FROMLIST(mylist, 2)
D3 <- GETDF_FROMLIST(mylist, 3)
D4 <- GETDF_FROMLIST(mylist, 4)

Hope that extra bit helps.

Cheers!


Very simple ! Here is my suggestion :

If you want to select dataframes in your workspace, try this :

Filter(function(x) is.data.frame(get(x)) , ls())

or

ls()[sapply(ls(), function(x) is.data.frame(get(x)))]

all these will give the same result.

You can change is.data.frame to check other types of variables like is.function

참고URL : https://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames

반응형