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"
Как вы можете видеть, имена столбцов один и два были заменены на X5 и X6.
Может кто-нибудь, пожалуйста, скажите мне, почему это происходит, и есть ли правильный способ сделать это без потери имен столбцов?
Решение для дробовика состояло в том, чтобы сохранить имена во вспомогательном векторе, а затем добавить их обратно, когда закончите работу с фреймом данных.
Спасибо
Context:
Я создал функцию, которая собирает некоторые данные и добавляет их как новую строку в кадр данных, полученный в качестве параметра.
Я создаю фрейм данных, перебираю через свои источники данных, передавая data.frame каждому вызову функции, который заполняется его результатами.
Ответы
Ответ 1
Страницы справки rbind
указывают, что:
Для 'cbind (' rbind) векторы нуля длина (включая "NULL" ) игнорируются если результат не будет иметь нулевые строки (столбцов), для S-совместимости. (Матрицы нулевой степени не встречаются в 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
Но может быть лучший способ сделать это в зависимости от вашего кода.
Ответ 2
Обходной путь:
a <- rbind(a, data.frame(one = 5, two = 6))
?rbind
указывает, что слияние объектов требует совпадения имен:
Затем он принимает классы столбцы из первого кадра данных и сопоставляет столбцы по имени (а не по положению)
Ответ 3
FWIW, альтернативный дизайн может иметь ваши функции для построения векторов для двух столбцов, а не для привязки к кадру данных:
ones <- c()
twos <- c()
Измените векторы в ваших функциях:
ones <- append(ones, 5)
twos <- append(twos, 6)
Повторите по мере необходимости, а затем создайте свой файл data.frame за один раз:
a <- data.frame(one=ones, two=twos)
Ответ 4
почти отказался от этой проблемы.
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
Ответ 5
Вы можете сделать это:
дать одну строку исходному кадру данных
df=data.frame(matrix(nrow=1,ncol=length(newrow))
добавьте новую строку и вытащите NAS
newdf=na.omit(rbind(newrow,df))
но следите за тем, чтобы ваш новорожденный не имел NA, или он также будет удален.
Приветствия
АГУС
Ответ 6
Один из способов сделать эту работу в целом и с наименьшим количеством повторных ввода имен столбцов - это следующее. Этот метод не требует взлома 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
>
Ответ 7
Я использую следующее решение для добавления строки в пустой фрейм данных:
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
НТН.
С уважением
Георг
Ответ 8
Вместо того, чтобы строить 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
Примечание: он испортил индекс (крайний левый). Я не понял, как предотвратить это (кто-то еще?), Но большую часть времени это, вероятно, не имеет значения.