Преобразование фрейма данных из широкого в длинный, но со столбцами в виде столбцов - PullRequest
1 голос
/ 27 февраля 2020

У меня есть большая база данных, в которой я работаю с 1500 строками. У меня есть фрейм данных в широком формате, но я хочу, чтобы он был в длинном формате, но столбцы должны быть сложены в виде строк. Я попытался использовать пакет изменения формы, который помог, но мне нужно получить столбцы в строках и пометить каждую строку, кроме имени inbred. У меня есть фрейм данных, готовый к go ... У меня есть два фрейма данных df является отправной точкой. df.actual - это фрейм данных, который я пытаюсь получить. Я использовал функцию изменения формы, чтобы складывать инбреды по столбцам по столбцам, которые должны быть снова сложены, как и инбреды. t stacked.

 reshape(df, varying= c("trait1","obs1","std.error1","trait2","obs2","std.error2"),
         idvar = "inbred", direction="long", sep="")
     inbred time trait obs std.error
x1.1     x1    1    12   2       0.2
x2.1     x2    1    43   2       0.3
x3.1     x3    1    23   3       0.2
x4.1     x4    1    65   2       0.4
x1.2     x1    2    14   3       0.1
x2.2     x2    2    53   3       0.4
x3.2     x3    2    63   2       0.5
x4.2     x4    2    68   2       0.6
> 

У меня проблемы с получением кадра данных для укладки строк и разметки этих строк по их инбредному имени.

 df.actual = data.frame(inbred=c("x1","x1","x1","x2","x2","x2","x3","x3","x3","x4","x4","x4"),metric=c("data.entry","obs","std.error","data.entry","obs","std.error","data.entry","obs","std.error","data.entry","obs","std.error"),trait1=c(12,2,.2,43,2,.3,23,3,.2,65,2,.4),
                                 trait2=c(14,3,.1,53,3,.4,63,2,.5,68,2,.6))
 df.actual
   inbred     metric trait1 trait2
1      x1 data.entry   12.0   14.0
2      x1        obs    2.0    3.0
3      x1  std.error    0.2    0.1
4      x2 data.entry   43.0   53.0
5      x2        obs    2.0    3.0
6      x2  std.error    0.3    0.4
7      x3 data.entry   23.0   63.0
8      x3        obs    3.0    2.0
9      x3  std.error    0.2    0.5
10     x4 data.entry   65.0   68.0
11     x4        obs    2.0    2.0
12     x4  std.error    0.4    0.6

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

Вы были почти там! Единственное, чего не хватало, так это того, что в данных есть два "trait"s, которые нужно учитывать. Решение состоит в том, чтобы поместить группы столбцов в список, что вы можете сделать по имени или номеру. Я буду использовать цифры здесь.

Чтобы создать желаемую переменную metrics на том же шаге, используйте 1. timevar, которая дает переменной time имя, и 2. times, которая присваивает имена временам (тип выдачи характер хотя).

reshape(df, list(2:4, 5:7), idvar="inbred", direction="long", 
        timevar="metric", times=c("trait", "obs", "std.error"))
#              inbred    metric trait1 trait2
# x1.trait         x1     trait   12.0   14.0
# x2.trait         x2     trait   43.0   53.0
# x3.trait         x3     trait   23.0   63.0
# x4.trait         x4     trait   65.0   68.0
# x1.obs           x1       obs    2.0    3.0
# x2.obs           x2       obs    2.0    3.0
# x3.obs           x3       obs    3.0    2.0
# x4.obs           x4       obs    2.0    2.0
# x1.std.error     x1 std.error    0.2    0.1
# x2.std.error     x2 std.error    0.3    0.4
# x3.std.error     x3 std.error    0.2    0.5
# x4.std.error     x4 std.error    0.4    0.6

После этого вы можете использовать order(), чтобы расположить строки при необходимости.

1 голос
/ 27 февраля 2020

Вот вариант с pivot_longer, где мы можем получить оба формата (второй формат), поменяв местами names_to.

library(dplyr)
library(tidyr) 
library(stringr)
df %>%
  pivot_longer(cols = -inbred, names_to = c("metric", ".value"),
    names_sep="(?<=[a-z])(?=\\d$)", 
     names_repair = ~ str_replace(., "^(\\d+)", "trait\\1")) %>%
  mutate(metric = replace(metric, metric == "trait", "data.entry"))
# A tibble: 12 x 4
#   inbred metric     trait1 trait2
#   <fct>  <chr>       <dbl>  <dbl>
# 1 x1     data.entry   12     14  
# 2 x1     obs           2      3  
# 3 x1     std.error     0.2    0.1
# 4 x2     data.entry   43     53  
# 5 x2     obs           2      3  
# 6 x2     std.error     0.3    0.4
# 7 x3     data.entry   23     63  
# 8 x3     obs           3      2  
# 9 x3     std.error     0.2    0.5
#10 x4     data.entry   65     68  
#11 x4     obs           2      2  
#12 x4     std.error     0.4    0.6

Если нам нужен reshape вывод

df %>%
  pivot_longer(cols = -inbred, names_to = c(".value", "metric"),
    names_sep="(?<=[a-z])(?=\\d$)")
# A tibble: 8 x 5
#  inbred metric trait   obs std.error
#  <fct>  <chr>  <dbl> <dbl>     <dbl>
#1 x1     1         12     2       0.2
#2 x1     2         14     3       0.1
#3 x2     1         43     2       0.3
#4 x2     2         53     3       0.4
#5 x3     1         23     3       0.2
#6 x3     2         63     2       0.5
#7 x4     1         65     2       0.4
#8 x4     2         68     2       0.6
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...