Как добавить именованный вектор в виде строки во фрейм данных, переупорядоченный в соответствии с порядком имен столбцов?

Как добавить именованный вектор во фрейм данных с компонентами вектора, переупорядоченными в соответствии с именами столбцов фрейма данных?

Мне нужно построить фрейм данных по одной строке за раз. Именованный вектор получается в результате некоторой обработки и предоставляет значения для вставляемой строки. Проблема в том, что именованный вектор не имеет компонентов в том же порядке, что и столбцы фрейма данных. Это приводит к тому, что rbind дает неверный результат. Вот очень упрощенный пример кода:

df = data.frame(id=1:2, va=11:12, vb=21:22, vc=31:32)
v1 = c(id=4, va=14, vb=25, vc=NA)
df = rbind(df, v1)

Пока все хорошо, поскольку это дает правильный результат. Теперь следующая обработка векторов приводит к:

v2 = c(va=19, id=9, vc=34, vb=NA)
df = rbind(df, v2)

Это дает неправильный результат. Правильный результат должен быть

id va vb vc
1  1 11 21 31
2  2 12 22 32
3  4 14 25 NA
4  9 19 NA 34

person kishore    schedule 22.03.2014    source источник
comment
Когда вы говорите Проблема в том, что именованный вектор не имеет компонентов в том же порядке, что и столбцы фрейма данных, почему вы не можете передать вектор имен столбцов и сделать так, чтобы он переупорядочивал внутри функция? Тогда вы могли бы сделать просто rbind   -  person smci    schedule 30.05.2018


Ответы (2)


Создайте фрейм данных из v2 до rbind:

rbind(df, as.data.frame(t(v2)))
##   id va vb vc
## 1  1 11 21 31
## 2  2 12 22 32
## 3  4 14 25 NA
## 4  9 19 NA 34

Вот почему это работает:

v2 имеет имена, но действует как вектор-столбец для as.data.frame:

as.data.frame(v2)
##    v2
## va 19
## id  9
## vc 34
## vb NA

Таким образом, вы должны транспонировать данные, чтобы привести их в правильную форму:

as.data.frame(t(v2))
##   va id vc vb
## 1 19  9 34 NA
person Matthew Lundberg    schedule 22.03.2014
comment
Спасибо за элегантный ответ и +1 за хорошее объяснение. Это служит моей цели довольно хорошо. - person kishore; 23.03.2014

Вы можете изменить порядок вектора

rbind(df, v2[names(df)])
  id va vb vc
1  1 11 21 31
2  2 12 22 32
3  9 19 NA 34


library(microbenchmark)
microbenchmark(rbind(df, v2[names(df)]),
               rbind(df, as.data.frame(t(v2))), times = 10000)
Unit: microseconds
                            expr     min      lq  median      uq      max neval
        rbind(df, v2[names(df)]) 212.773 219.305 222.572 294.895 15300.96 10000
 rbind(df, as.data.frame(t(v2))) 374.219 382.618 387.750 516.067 39951.31 10000
person Julius Vainora    schedule 22.03.2014
comment
Это также принимает короткий вектор для v2, заполняя отсутствующие значения с помощью NA. Это может быть преимуществом в некоторых ситуациях (и может скрыть ошибки в других — он даже молча примет вектор со слишком большим количеством элементов). - person Matthew Lundberg; 22.03.2014
comment
Интересный способ. Мне нужно посмотреть на это в контексте того, что v2 является коротким вектором. У меня может быть похожая ситуация. - person kishore; 23.03.2014