Programing

행 단위로 R 데이터 프레임 만들기

lottogame 2020. 8. 16. 21:43
반응형

행 단위로 R 데이터 프레임 만들기


R에서 행 단위로 데이터 프레임을 구성하고 싶습니다. 몇 가지 검색을 수행했으며 빈 목록을 만들고 목록 인덱스 스칼라를 유지 한 다음 매번 목록에 추가하라는 제안 만했습니다. 단일 행 데이터 프레임을 만들고 목록 인덱스를 1 씩 앞으로 이동합니다. 마지막으로 do.call(rbind,)목록에 있습니다.

이것이 작동하는 동안 매우 번거로운 것 같습니다. 동일한 목표를 달성하는 더 쉬운 방법이 없습니까?

분명히 일부 apply기능을 사용할 수없고 명시 적으로 데이터 프레임을 행 단위로 만들어야하는 경우를 언급합니다 . 적어도 push사용 된 마지막 인덱스를 명시 적으로 추적하는 대신 목록의 끝 으로가는 방법이 있습니까?


을 추가하거나 사용하여 행별로 늘릴 수 있습니다 rbind().

그렇다고해서 그래야한다는 의미는 아닙니다. 동적으로 성장하는 구조는 R에서 코딩하는 가장 효율적인 방법 중 하나입니다.

가능하다면 전체 data.frame을 미리 할당하십시오.

N <- 1e4  # total number of rows to preallocate--possibly an overestimate

DF <- data.frame(num=rep(NA, N), txt=rep("", N),  # as many cols as you need
                 stringsAsFactors=FALSE)          # you don't know levels yet

그런 다음 작업 중에 한 번에 행을 삽입하십시오.

DF[i, ] <- list(1.4, "foo")

임의의 data.frame에서 작동하고 훨씬 더 효율적입니다. N을 초과하면 항상 끝에서 빈 행을 축소 할 수 있습니다.


행을 추가 할 수 있습니다 NULL.

df<-NULL;
while(...){
  #Some code that generates new row
  rbind(df,row)->df
}

예를 들어

df<-NULL
for(e in 1:10) rbind(df,data.frame(x=e,square=e^2,even=factor(e%%2==0)))->df
print(df)

이것은 [와 유사한 ] do.call(rbind,)의 출력에 사용하는 방법에 대한 어리석은 예입니다 .Map()lapply()

> DF <- do.call(rbind,Map(function(x) data.frame(a=x,b=x+1),x=1:3))
> DF
  x y
1 1 2
2 2 3
3 3 4
> class(DF)
[1] "data.frame"

이 구조를 자주 사용합니다.


내가 Rcpp를 너무 좋아하는 이유는 항상 R Core가 어떻게 생각하는지 이해하지 못하기 때문이며 Rcpp를 사용하면 더 자주 그렇지 않아도됩니다.

철학적으로 말하면 모든 가치 다른 모든 가치와 독립적으로 나타나 도록하는 기능적 패러다임과 관련하여 당신은 죄의 상태에 있습니다 . 하나의 값을 변경하면 C에서 표현을 공유하는 포인터와 같은 방식으로 다른 값에 가시적 인 변경이 발생해서는 안됩니다.

함수형 프로그래밍이 작은 우주선에 방해가되지 않도록 신호를 보내고 작은 우주선이 "I 'm a lighthouse"라고 답할 때 문제가 발생합니다. 그 동안 처리하려는 큰 물체에 긴 일련의 작은 변경을 수행하면 등대 영역으로 들어갈 수 있습니다.

C ++ STL에서는 push_back()삶의 방식입니다. 기능성을 발휘하지는 않지만 일반적인 프로그래밍 관용구를 효율적 으로 수용하려고합니다 .

무대 뒤에서 약간의 영리함을 통해 때때로 각 세계에서 한 발을 갖도록 할 수 있습니다. 스냅 샷 기반 파일 시스템이 좋은 예입니다 (양쪽을 연결하는 유니온 마운트와 같은 개념에서 발전).

R Core가이 작업을 수행하려는 경우 기본 벡터 저장소가 유니온 마운트처럼 작동 할 수 있습니다. 벡터 저장소에 대한 한 참조는 첨자 1:N대해 유효 할 수 있지만 동일한 저장에 대한 다른 참조는 첨자에 유효합니다 1:(N+1). 아직 유효하게 참조되지 않은 예약 된 저장소가있을 수 있지만 빠른 push_back(). 기존 참조가 유효하다고 간주하는 범위 밖에 추가 할 때 기능 개념을 위반하지 않습니다.

결국 행을 점진적으로 추가하면 예약 된 스토리지가 부족합니다. 저장소에 약간의 증분을 곱하여 모든 항목의 새 복사본을 만들어야합니다. 내가 사용한 STL 구현은 할당을 확장 할 때 스토리지에 2를 곱하는 경향이 있습니다. R Internals에서 스토리지가 20 % 씩 증가하는 메모리 구조가 있다고 읽었습니다. 어느 쪽이든 추가 된 총 요소 수에 대한 대수 빈도로 증가 작업이 발생합니다. 상각 기준으로 이것은 일반적으로 허용됩니다.

뒤에서 트릭이 진행됨에 따라 나는 더 나빠졌습니다. push_back()데이터 프레임에 새 행을 올릴 때마다 최상위 인덱스 구조를 복사해야합니다. 새 행은 이전 기능 값에 영향을주지 않고 공유 표현에 추가 될 수 있습니다. 나는 그것이 가비지 수집기를 많이 복잡하게 만들 것이라고 생각조차하지 않는다. push_front()모든 참조가 할당 된 벡터 스토리지의 앞쪽에 대한 접두사 참조 라고 제안하지 않기 때문에 .


Dirk Eddelbuettel의 대답이 최고입니다. 여기에서는 데이터 프레임 차원 또는 데이터 유형을 미리 지정하지 않아도됩니다. 여러 데이터 유형과 많은 열이있는 경우 유용 할 수 있습니다.

row1<-list("a",1,FALSE) #use 'list', not 'c' or 'cbind'!
row2<-list("b",2,TRUE)  

df<-data.frame(row1,stringsAsFactors = F) #first row
df<-rbind(d,row2) #now this works as you'd expect.

행렬없이 원시 데이터 프레임을 만드는 방법을 찾았습니다.

자동 열 이름 사용

df<-data.frame(
        t(data.frame(c(1,"a",100),c(2,"b",200),c(3,"c",300)))
        ,row.names = NULL,stringsAsFactors = FALSE
    )

열 이름 포함

df<-setNames(
        data.frame(
            t(data.frame(c(1,"a",100),c(2,"b",200),c(3,"c",300)))
            ,row.names = NULL,stringsAsFactors = FALSE
        ), 
        c("col1","col2","col3")
    )

If you have vectors destined to become rows, concatenate them using c(), pass them to a matrix row-by-row, and convert that matrix to a dataframe.

For example, rows

dummydata1=c(2002,10,1,12.00,101,426340.0,4411238.0,3598.0,0.92,57.77,4.80,238.29,-9.9)
dummydata2=c(2002,10,2,12.00,101,426340.0,4411238.0,3598.0,-3.02,78.77,-9999.00,-99.0,-9.9)
dummydata3=c(2002,10,8,12.00,101,426340.0,4411238.0,3598.0,-5.02,88.77,-9999.00,-99.0,-9.9)

can be converted to a data frame thus:

dummyset=c(dummydata1,dummydata2,dummydata3)
col.len=length(dummydata1)
dummytable=data.frame(matrix(data=dummyset,ncol=col.len,byrow=TRUE))

Admittedly, I see 2 major limitations: (1) this only works with single-mode data, and (2) you must know your final # columns for this to work (i.e., I'm assuming that you're not working with a ragged array whose greatest row length is unknown a priori).

This solution seems simple, but from my experience with type conversions in R, I'm sure it creates new challenges down-the-line. Can anyone comment on this?

참고URL : https://stackoverflow.com/questions/3642535/creating-an-r-dataframe-row-by-row

반응형