Как преобразовать строку в столбец на основе одной строки в R? - PullRequest
1 голос
/ 04 мая 2020

У меня есть набор данных, который выглядит примерно так

A    B    1960 1970 1980
x    a    1    2    3
x    b    1.1  2.1  NA
y    a    2    3    4
y    b    1    NA   1

Я хочу преобразовать столбцы на основе строки B, чтобы они выглядели примерно так

A    year       a    b
x    1960    1   1.1    
x    1970    2   2.1
x    1980    3   NA    
y    1960    2   1
y    1970    3   NA
y    1980    4   1

Я не уверен, как это сделать. Я знаю, что могу сделать полное преобразование, используя t () или row_to_columns () из tidyverse, но результат не тот, который я хочу. Исходные данные имеют около 60 столбцов и 165 различных значений в столбце B.

Ответы [ 3 ]

2 голосов
/ 04 мая 2020

Вы можете сделать pivot_long(), а затем pivot_wide(), хотя может быть плохой идеей переименовать ваш столбец "B" снова:

library(dplyr)
library(tidyr)

df %>% pivot_longer(-c(A,B)) %>% 
pivot_wider(names_from=B) %>% rename(B=name)

    # A tibble: 6 x 4
  A     B         a     b
  <fct> <chr> <dbl> <dbl>
1 x     1960      1   1.1
2 x     1970      2   2.1
3 x     1980      3  NA  
4 y     1960      2   1  
5 y     1970      3  NA  
6 y     1980      4   1 

df = structure(list(A = structure(c(1L, 1L, 2L, 2L), .Label = c("x", 
"y"), class = "factor"), B = structure(c(1L, 2L, 1L, 2L), .Label = c("a", 
"b"), class = "factor"), `1960` = c(1, 1.1, 2, 1), `1970` = c(2, 
2.1, 3, NA), `1980` = c(3L, NA, 4L, 1L)), class = "data.frame", row.names = c(NA, 
-4L))
0 голосов
/ 04 мая 2020

Решение Base R:

long_df <- reshape(df, direction = "long", 
        varying = which(!names(df) %in% c("A", "B")),
        v.names = "value",
        timevar = "year",
        times = names(df)[!(names(df) %in% c("A", "B"))],
        ids = NULL,
        new.row.names = 1:(length(which(!names(df) %in% c("A", "B"))) * nrow(df)))


wide_df <- setNames(reshape(long_df, direction = "wide", 
                   idvar = c("A", "year"),
                   timevar = "B"), c("A", "B", unique(df$B)))

Данные:

df <- structure(list(A = c("x", "x", "y", "y"), B = c("a", "b", "a", 
"b"), `1960` = c(1, 1.1, 2, 1), `1970` = c(2, 2.1, 3, NA), `1980` = c(3L, 
NA, 4L, 1L)), row.names = 2:5, class = "data.frame")
0 голосов
/ 04 мая 2020
library(data.table)

dt <- fread('A    B    1960 1970 1980
x    a    1    2    3
x    b    1.1  2.1  NA
y    a    2    3    4
y    b    1    NA   1')

names(dt) <- as.character(dt[1,])
dt <- dt[-1,]
dt[,(3:5):=lapply(.SD,as.numeric),.SDcols=3:5]
dcast(melt(dt,measure.vars = 3:5),...~B,value.var = "value")
#>    A variable a   b
#> 1: x     1960 1 1.1
#> 2: x     1970 2 2.1
#> 3: x     1980 3  NA
#> 4: y     1960 2 1.0
#> 5: y     1970 3  NA
#> 6: y     1980 4 1.0

Создано в 2020-05-05 пакетом Представления (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...