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, 대체 설계에는 데이터 프레임에 rbinding하는 대신 두 열에 대한 벡터를 빌드하는 함수가있을 수 있습니다.
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
>
Another way to do this more cleanly is to use 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
Notice that a data.table is also a data.frame.
> class(df)
"data.table" "data.frame"
You can do this:
give one row to the initial data frame
df=data.frame(matrix(nrow=1,ncol=length(newrow))
add your new row and take out the NAS
newdf=na.omit(rbind(newrow,df))
but watch out that your newrow does not have NAs or it will be erased too.
Cheers Agus
I use the following solution to add a row to an empty data frame:
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.
Kind regards
Georg
Instead of constructing the data.frame with numeric(0)
I use as.numeric(0)
.
a<-data.frame(one=as.numeric(0), two=as.numeric(0))
This creates an extra initial row
a
# one two
#1 0 0
Bind the additional rows
a<-rbind(a,c(5,6))
a
# one two
#1 0 0
#2 5 6
Then use negative indexing to remove the first (bogus) row
a<-a[-1,]
a
# one two
#2 5 6
Note: it messes up the index (far left). I haven't figured out how to prevent that (anyone else?), but most of the time it probably doesn't matter.
'Nice programing' 카테고리의 다른 글
2038 년에 대비하려면 어떻게해야합니까? (0) | 2020.12.05 |
---|---|
http 기본 인증 "로그 아웃" (0) | 2020.12.05 |
jQuery로 Textarea 값 얻기 (0) | 2020.12.05 |
React에서 컴포넌트간에 기능을 공유하는 올바른 방법 (0) | 2020.12.05 |
Linux USB : 전원 켜기 및 끄기? (0) | 2020.12.05 |