Измените значения из 1 столбца и присоедините к существующему имени столбца - PullRequest
0 голосов
/ 09 мая 2018

У меня есть набор данных, который выглядит следующим образом:

Col1     Col2    Col3   Col4    Col5
   A        1       1     10      90
   A        1       2     20     100 
   A        1       3     30     110 
   A        1       4     40     120
   B        2       1     50     130
   B        2       2     60     140 
   B        2       3     70     150
   B        2       4     80     160

Как мне изменить это так, чтобы у меня было значение из Col1 в имени столбца всех столбцов из Col4 и далее?Мой фактический набор данных имеет около 20 столбцов.

Я хочу, чтобы мой конечный результат выглядел так:

Col2    Col3   Col4_A    Col4_B      Col5_A      Col5_B
   1       1       10        NA          90          NA
   1       2       20        NA         100          NA
   1       3       30        NA         110          NA
   1       4       40        NA         120          NA 
   2       1       NA        50          NA         130
   2       2       NA        60          NA         140
   2       3       NA        70          NA         150
   2       4       NA        80          NA         160

Ответы [ 3 ]

0 голосов
/ 10 мая 2018

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

library('data.table')

Данные-1:

df1 <- read.table(text='Col1     Col2    Col3   Col4    Col5
A        1       1     10      90
                  A        1       2     20     100 
                  A        1       3     30     110 
                  A        1       4     40     120
                  B        1       1     50     130
                  B        1       2     60     140 
                  B        1       3     70     150
                  B        1       4     80     160', header = TRUE)

setDT(df1)
value.var <- names(df1)[!names(df1) %in% c('Col1', 'Col2', 'Col3')]
dcast(df1, Col2 + Col3 ~ Col1, value.var = value.var )
#    Col2 Col3 Col5_A Col5_B Col4_A Col4_B
# 1:    1    1     90    130     10     50
# 2:    1    2    100    140     20     60
# 3:    1    3    110    150     30     70
# 4:    1    4    120    160     40     80

Данные-2:

df2 <- read.table(text='Col1     Col2    Col3   Col4    Col5
   A        1       1     10      90
                  A        1       2     20     100 
                  A        1       3     30     110 
                  A        1       4     40     120
                  B        2       1     50     130
                  B        2       2     60     140 
                  B        2       3     70     150
                  B        2       4     80     160', header = TRUE)
setDT(df2)
value.var <- names(df2)[!names(df2) %in% c('Col1', 'Col2', 'Col3')]
dcast(df2, Col2 + Col3 ~ Col1, value.var = value.var )

#    Col2 Col3 Col5_A Col5_B Col4_A Col4_B
# 1:    1    1     90     NA     10     NA
# 2:    1    2    100     NA     20     NA
# 3:    1    3    110     NA     30     NA
# 4:    1    4    120     NA     40     NA
# 5:    2    1     NA    130     NA     50
# 6:    2    2     NA    140     NA     60
# 7:    2    3     NA    150     NA     70
# 8:    2    4     NA    160     NA     80
0 голосов
/ 10 мая 2018

Вот базовый метод R с model.matrix и sub.

# construct desired data.frame
dat <- as.data.frame(model.matrix(~Col2 + Col3 + Col1:(Col4 + Col5) - 1, df1))
# construct desired names
names(dat) <- sub("^.*(.):(.*)$", "\\2\\1", names(dat))

Здесь формула в model.matrix используется для построения желаемой структуры. -1 в конце гарантирует, что каждый уровень взаимодействия появляется. Поскольку функция возвращает матрицу, используйте as.data.frame для ее преобразования. Затем используйте sub и регулярное выражение, чтобы изменить имена переменных взаимодействия. Это возвращает

dat
  Col2 Col3 Col4A Col4B Col5A Col5B
1    1    1    10     0    90     0
2    1    2    20     0   100     0
3    1    3    30     0   110     0
4    1    4    40     0   120     0
5    1    1     0    50     0   130
6    1    2     0    60     0   140
7    1    3     0    70     0   150
8    1    4     0    80     0   160

Обратите внимание, что если вы планируете использовать это непосредственно в модели, вы, вероятно, не хотите преобразовывать его в data.frame. В случае если матрица остается, замените names(dat) на colnames(dat).

Используйте sub("^.*(.):(.*)$", "\\2_\\1", names(dat)) для включения подчеркивания.

Чтобы сделать первую часть более динамичной, вы можете создать формулу для функции model.matrix с помощью функции, подобной этой:

f <- function(x) as.formula(paste0("~ Col2 + Col3 + Col1:(",
                                   paste(paste0("Col", x), collapse=" + "), ") -1"))

Тогда попробуйте,

f(4:7)
~Col2 + Col3 + Col1:(Col4 + Col5 + Col6 + Col7) - 1
<environment: 0x3d2b598>
0 голосов
/ 09 мая 2018

Мы можем использовать gather, unite и spread от tidyr:

library(dplyr)
library(tidyr)

df %>%
  gather(var, value, -(Col1:Col3)) %>%
  unite(var, var, Col1, sep="_") %>%
  spread(var, value)

Результат:

  Col2 Col3 Col4_A Col4_B Col5_A Col5_B
1    1    1     10     NA     90     NA
2    1    2     20     NA    100     NA
3    1    3     30     NA    110     NA
4    1    4     40     NA    120     NA
5    2    1     NA     50     NA    130
6    2    2     NA     60     NA    140
7    2    3     NA     70     NA    150
8    2    4     NA     80     NA    160
...