#r #tidyverse
Вопрос:
Рассмотрим char
фрейм данных 3×3:
example lt;- data.frame(one = c("a","b","c"), two = c("a","b","b"), three = c ("c","a","b"))
Я хочу изменить размер этих данных до 6×2 и добавить следующий контент:
desired lt;- data.frame(one = c("a","a","b","b", "c","b"), two = c("a","c","b","a","b","b"))
Для исходного кадра данных примера я хочу rbind()
просмотреть содержимое примера [,2:3]
под каждым индексом строки.
Этого можно достичь путем:
ex lt;- as.matrix(example) des lt;- as.data.frame(rbind(ex[,1:2], ex[,2:3]))
Может library(tidyverse)
быть, было бы лучше использовать произвольное количество столбцов?
Ответ №1:
Для каждой пары столбцов транспонируйте определенный ими фрейм субданных и принудительно преобразуйте его в вектор. Затем принудительно введите data.frame и задайте имена результатов.
Приведенный ниже код должен быть масштабируемым, он не жестко определяет количество столбцов.
desired2 lt;- as.data.frame( lapply(seq(names(example))[-1], (k) c(t(example[(k-1):k]))) ) names(desired2) lt;- names(example)[-ncol(example)] identical(desired, desired2) #[1] TRUE
Приведенный выше код переписан как функция.
reformat lt;- function(x){ y lt;- as.data.frame( lapply(seq(names(x))[-1], (k) c(t(x[(k-1):k]))) ) names(y) lt;- names(x)[-ncol(x)] y } reformat(example) example %gt;% reformat()
Другой пример, с вводом 6 столбцов.
ex1 lt;- example ex2 lt;- example names(ex2) lt;- c("fourth", "fifth", "sixth") ex lt;- cbind(ex1, ex2) reformat(ex) ex %gt;% reformat()
Комментарии:
1. Это чистый метод, но я получаю ошибку при определении функции: «неожиданно «)» в «)». Мне интересно, имеет ли это какое-то отношение к этому
/(k)
?2. @M1996rg Может быть, так оно и есть.
(k)
это новая лямбда, введенная в R4.1.0. Попробуйтеfunction(k)
. Время обновить R?
Ответ №2:
tidyverse
Подход, использующий tidyr::pivot_longer
может выглядеть так:
library(dplyr) library(tidyr) pivot_longer(example, -one, values_to = "two") %gt;% select(-name) #gt; # A tibble: 6 × 2 #gt; one two #gt; lt;chrgt; lt;chrgt; #gt; 1 a a #gt; 2 a c #gt; 3 b b #gt; 4 b a #gt; 5 c b #gt; 6 c b
Ответ №3:
Решение base-R с Map
:
#iterate over example$one, example$two, and example$three at the same #time, creating the output you need. mylist lt;- Map(function(x ,y ,z ) { data.frame(one = c(x, y), two = c(y, z)) }, example$one #x, example$two #y, example$three #z) do.call(rbind, mylist) one two a.1 a a a.2 a c b.1 b b b.2 b a c.1 c b c.2 b b