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.
может кто-то пожалуйста, скажите мне, почему это происходит и есть ли правильный способ сделать это без потери колонка имена?
решение дробовика будет заключаться в том, чтобы сохранить имена во вспомогательном векторе, а затем добавить их обратно, когда закончите работу над фреймом данных.
спасибо
контекст:
Я создал функцию, которая собирает некоторые данные и добавляет их в качестве новой строки в таблицу данных полученных в качестве параметра. Я создаю фрейм данных, перебираю свои источники данных, передавая данные.кадр для каждого вызова функции должен быть заполнен его результатами.
8 ответов:
The
rbind
страницы справки указывает, что:для ' cbind '(’rbind'), векторов нуля длина (включая ‘NULL’) игнорируются если результат не будет иметь нулевых строк (столбцов), для совместимости С. (Матрицы нулевой степени не встречаются в S3 и не игнорируются в р.)
так, на самом деле,
a
игнорируется вrbind
инструкция. Не полностью игнорируется, кажется, потому что как это фрейм данных
почти сдался этому вопросу.
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)
повторите по мере необходимости, затем создайте свои данные.кадр на одном дыхании:
a <- data.frame(one=ones, two=twos)
Вы можете сделать это:
Дайте одну строку в начальный фрейм данных
df=data.frame(matrix(nrow=1,ncol=length(newrow))
добавить новую строку и вынуть NAS
newdf=na.omit(rbind(newrow,df))
но будьте осторожны, что ваш newrow не имеет NAs или он будет стерт тоже.
Ура Агус
Я использую следующее решение, чтобы добавить строку в пустой фрейм данных:
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.
С уважением
Георг
один из способов сделать эту работу в целом и с наименьшим количеством повторного ввода имен столбцов заключается в следующем. Этот метод не требует взлома 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 >
другой способ сделать это более аккуратно использовать данные.таблица:
> 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
обратите внимание, что данные.таблица также является данными.рамка.
> class(df) "data.table" "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
Примечание: это портит индекс (крайний слева). Я не понял, как предотвратить это (кто-нибудь еще?), но в большинстве случаев это, вероятно, не имеет значения.