sourcecode

R: 빈 데이터 프레임에 행을 추가할 때 열 이름이 손실됨

copyscript 2023. 11. 5. 14:56
반응형

R: 빈 데이터 프레임에 행을 추가할 때 열 이름이 손실됨

저는 막 R부터 시작하는데 이상한 동작을 당했습니다. 빈 데이터 프레임에 첫 번째 행을 삽입하면 원래 열 이름이 손실됩니다.

예:

a<-data.frame(one = numeric(0), two = numeric(0))
a
#[1] one two
#<0 rows> (or 0-length row.names)
names(a)
#[1] "one" "two"
a<-rbind(a, c(5,6))
a
#  X5 X6
#1  5  6
names(a)
#[1] "X5" "X6"

보시다시피 열 이름 12X5X6로 대체되었습니다.

누가 왜 이런 일이 생기는지 그리고 칼럼 이름을 잃지 않고 이것을 할 수 있는 올바른 방법이 있는지 알려주실 수 있나요?

산탄총 솔루션은 이름을 보조 벡터에 저장했다가 데이터 프레임 작업이 끝나면 다시 추가하는 것입니다.

감사해요.

컨텍스트:

일부 데이터를 모아서 파라미터로 받은 데이터 프레임에 새로운 행으로 추가하는 함수를 만들었습니다.데이터 프레임을 만들고 데이터 소스를 반복하여 각 함수 호출에 data.frame을 전달하여 결과를 채웁니다.

rbind도움말 페이지는 다음을 지정합니다.

'cbind'('rbind')의 경우 S 호환성의 경우 결과에 행(열)이 0이 아닌 한 0 길이의 벡터('NULL' 포함)는 무시됩니다.(제로 익스텐트 행렬은 S3에서는 발생하지 않으며 R에서는 무시되지 않습니다.)

그래서 사실은.a당신의 안에서 무시됩니다.rbind설명.완전히 무시된 것은 아닌 것 같습니다. 왜냐하면 그것이 데이터 프레임이기 때문입니다.rbind함수는 다음과 같이 불립니다.rbind.data.frame:

rbind.data.frame(c(5,6))
#  X5 X6
#1  5  6

행을 삽입하는 한 가지 방법은 다음과 같습니다.

a[nrow(a)+1,] <- c(5,6)
a
#  one two
#1   5   6

하지만 코드에 따라 더 좋은 방법이 있을지도 모릅니다.

이 문제에 거의 굴복하고 있었습니다.

1) 데이터 프레임 생성:stringsAsFactor로 설정.FALSE아니면 다음 호로 곧장 달려가거나

2) 쓰지 마rbind- 도대체 왜 칼럼 이름을 엉망으로 만드는지 모르겠어요.이렇게 하면 됩니다.

df[nrow(df)+1,] <- c("d","gsgsgd",4)

df <- data.frame(a = character(0), b=character(0), c=numeric(0))

df[nrow(df)+1,] <- c("d","gsgsgd",4)

#Warnmeldungen:
#1: In `[<-.factor`(`*tmp*`, iseq, value = "d") :
#  invalid factor level, NAs generated
#2: In `[<-.factor`(`*tmp*`, iseq, value = "gsgsgd") :
#  invalid factor level, NAs generated

df <- data.frame(a = character(0), b=character(0), c=numeric(0), stringsAsFactors=F)

df[nrow(df)+1,] <- c("d","gsgsgd",4)

df
#  a      b c
#1 d gsgsgd 4

해결 방법은 다음과 같습니다.

a <- rbind(a, data.frame(one = 5, two = 6))

?rbind개체를 병합하려면 일치하는 이름이 필요합니다.

그런 다음 첫 번째 데이터 프레임에서 열의 클래스를 가져와 위치별이 아닌 이름별로 열을 매칭합니다.

FWIW, 대체 설계에서는 데이터 프레임에 바인딩하는 대신 두 열에 대한 벡터를 생성하는 함수를 사용할 수 있습니다.

ones <- c()
twos <- c()

함수의 벡터를 수정합니다.

ones <- append(ones, 5)
twos <- append(twos, 6)

필요에 따라 반복한 다음 data.frame을 한 번에 생성합니다.

a <- data.frame(one=ones, two=twos)

열 이름의 재입력을 최소화하고 일반적으로 작업할 수 있도록 하는 한 가지 방법은 다음과 같습니다.이 방법은 NA나 0을 해킹할 필요가 없습니다.

rs <- data.frame(i=numeric(), square=numeric(), cube=numeric())
for (i in 1:4) {
    calc <- c(i, i^2, i^3)
    # append calc to rs
    names(calc) <- names(rs)
    rs <- rbind(rs, as.list(calc))
}

rs는 정확한 이름을 가질 것입니다.

> rs
    i square cube
1   1      1    1
2   2      4    8
3   3      9   27
4   4     16   64
> 

이 작업을 보다 깨끗하게 수행하는 또 다른 방법은 data.table을 사용하는 것입니다.

> df <- data.frame(a=numeric(0), b=numeric(0))
> rbind(df, list(1,2)) # column names are messed up
>   X1 X2
> 1  1  2

> df <- data.table(a=numeric(0), b=numeric(0))
> rbind(df, list(1,2)) # column names are preserved
   a b
1: 1 2

data.table도 data.frame입니다.

> class(df)
"data.table" "data.frame"

다음을 수행할 수 있습니다.

초기 데이터 프레임에 행 하나를 지정합니다.

 df=data.frame(matrix(nrow=1,ncol=length(newrow))

새 행을 추가하고 NAS를 꺼냅니다.

newdf=na.omit(rbind(newrow,df))

하지만 새 행에 NA가 없거나 삭제될 수 있으니 주의하시기 바랍니다.

치어스 아구스

다음 솔루션을 사용하여 빈 데이터 프레임에 행을 추가합니다.

d_dataset <- 
  data.frame(
    variable = character(),
    before = numeric(),
    after = numeric(),
    stringsAsFactors = FALSE)

d_dataset <- 
  rbind(
    d_dataset,
      data.frame(
        variable = "test",
        before = 9,
        after = 12,
        stringsAsFactors = FALSE))  

print(d_dataset)

variable before after  
1     test      9    12

HTH.

안부의 말

게오르크

data.frame을 구성하는 대신numeric(0)사용합니다.as.numeric(0).

a<-data.frame(one=as.numeric(0), two=as.numeric(0))

추가 초기 행이 생성됩니다.

a
#    one two
#1   0   0

추가 행 바인딩

a<-rbind(a,c(5,6))
a
#    one two
#1   0   0
#2   5   6

그런 다음 네거티브 인덱싱을 사용하여 첫 번째(보기) 행을 제거합니다.

a<-a[-1,]
a

#    one two
#2   5   6

참고: 인덱스(맨 왼쪽)를 엉망으로 만듭니다.저는 그것을 예방하는 방법을 찾지 못했지만(다른 사람은?), 대부분의 경우 그것은 아마 중요하지 않을 것입니다.

이 존경할 만한 R의 귀찮음을 조사하는 것이 나를 이 페이지로 이끌었습니다.OP(losing 필드명)가 제기하는 문제를 해결할 뿐만 아니라 모든 분야가 원치 않게 인자로 전환되는 것을 막아주는 Georg의 훌륭한 답변(https://stackoverflow.com/a/41609844/2757825), 에 조금 더 설명을 덧붙이고 싶었습니다.저는 그 두 가지 문제가 잘 맞습니다.저는 추가 코드를 작성하는 것을 수반하지 않지만 두 가지 다른 연산을 보존하는 R 기반 솔루션을 원했습니다. 데이터 프레임을 정의하고 행을 추가합니다. 이것이 Georg의 대답이 제공하는 것입니다.

아래의 첫 두 예는 문제를 설명하고 세 번째와 네 번째는 Georg의 해결책을 보여줍니다.

예제 1: 새 행을 벡터로 추가하고 rbind를 사용합니다.

  • 결과: 열 이름을 잃고 모든 변수를 요인으로 덮어씁니다.
my.df <- data.frame(
    table = character(0),
    score = numeric(0),
    stringsAsFactors=FALSE
    )
my.df <- rbind(
    my.df, 
    c("Bob", 250) 
    )
    
my.df
  X.Bob. X.250.
1    Bob    250

str(my.df)
'data.frame':   1 obs. of  2 variables:
 $ X.Bob.: Factor w/ 1 level "Bob": 1
 $ X.250.: Factor w/ 1 level "250": 1

예제 2: 새 행을 rbind 내부의 데이터 프레임으로 추가

  • 결과: 열 이름은 유지하지만 문자 변수를 인자로 변환합니다.
my.df <- data.frame(
    table = character(0),
    score = numeric(0),
    stringsAsFactors=FALSE
    )
my.df <- rbind(
    my.df, 
    data.frame(name="Bob", score=250) 
    )
    
my.df
      name score
1 Bob  250

str(my.df)
'data.frame':   1 obs. of  2 variables:
 $ name : Factor w/ 1 level "Bob": 1
 $ score: num 250

예제 3: rbind 내부의 새 행을 데이터 프레임으로 추가하고 문자열AsFactors= false

  • 결과: 문제가 해결되었습니다.
my.df <- data.frame(
    table = character(0),
    score = numeric(0),
    stringsAsFactors=FALSE
    )
my.df <- rbind(
    my.df, 
    data.frame(name="Bob", score=250, stringsAsFactors=FALSE) 
    )
    
my.df
      name score
1 Bob  250

str(my.df)
'data.frame':   1 obs. of  2 variables:
 $ name : chr "Bob"
 $ score: num 250

예제 4: 예제 3처럼 여러 행을 한 번에 추가합니다.

my.df <- data.frame(
    table = character(0),
    score = numeric(0),
    stringsAsFactors=FALSE
    )
my.df <- rbind(
    my.df, 
    data.frame(
        name=c("Bob", "Carol", "Ted"), 
        score=c(250, 124, 95), 
        stringsAsFactors=FALSE) 
    )

str(my.df)
'data.frame':   3 obs. of  2 variables:
 $ name : chr  "Bob" "Carol" "Ted"
 $ score: num  250 124 95

my.df
   name score
1   Bob   250
2 Carol   124
3   Ted    95

사용가능add_row로부터tibble패키지:

tibble::add_row(a, one = c(5, 10), two = c(6, 8))

산출량

  one two
1   5   6
2  10   8

언급URL : https://stackoverflow.com/questions/5231540/r-losing-column-names-when-adding-rows-to-an-empty-data-frame

반응형