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"
보시다시피 열 이름 1과 2는 X5와 X6로 대체되었습니다.
누가 왜 이런 일이 생기는지 그리고 칼럼 이름을 잃지 않고 이것을 할 수 있는 올바른 방법이 있는지 알려주실 수 있나요?
산탄총 솔루션은 이름을 보조 벡터에 저장했다가 데이터 프레임 작업이 끝나면 다시 추가하는 것입니다.
감사해요.
컨텍스트:
일부 데이터를 모아서 파라미터로 받은 데이터 프레임에 새로운 행으로 추가하는 함수를 만들었습니다.데이터 프레임을 만들고 데이터 소스를 반복하여 각 함수 호출에 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
'sourcecode' 카테고리의 다른 글
MySQL에서 쿼리에 의해 반환되는 각 행에 대해 저장 프로시저 호출 (0) | 2023.11.05 |
---|---|
데이터베이스 연결이 항상 열려 있어야 합니까, 아니면 필요할 때만 열려 있어야 합니까? (0) | 2023.11.05 |
입력 type= 텍스트를 비활성화하는 방법? (0) | 2023.11.05 |
현재 디렉터리에서 .tar.gz를 추출하는 방법? (하위 폴더 없음) (0) | 2023.11.05 |
데이터베이스, 테이블 및 열 이름 지정 규칙? (0) | 2023.11.05 |