Подтвердить что ты не робот

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 каждому вызову функции, который заполняется его результатами.

4b9b3361

Ответ 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

Примечание: он испортил индекс (крайний левый). Я не понял, как предотвратить это (кто-то еще?), Но большую часть времени это, вероятно, не имеет значения.