расширение (взрыв?) объекта data.frame путем добавления переменной, содержащей порядковый номер, с помощью dplyr - PullRequest
4 голосов
/ 20 марта 2019

У меня есть простой фрейм данных, скажем:

dd <- data.frame(id = letters[1:4], v1 = c(0.3,0.1,0.7,1.3))
dd
  id  v1
1  a 0.3
2  b 0.1
3  c 0.7
4  d 1.3

Для каждой строки этого фрейма данных я хочу «взорвать» его, добавив новую переменную, которая дает последовательность чисел. Мне это удалось, но мой код не идеален и едва ли подойдет:

dd %>% 
  mutate("0"=0,"5"=5,"10"=10) %>% 
  reshape2::melt(id.vars=c("id", "v1")) %>% 
  select(-variable) 
   id  v1 value
1   a 0.3     0
2   b 0.1     0
3   c 0.7     0
4   d 1.3     0
5   a 0.3     5
6   b 0.1     5
7   c 0.7     5
8   d 1.3     5
9   a 0.3    10
10  b 0.1    10
11  c 0.7    10
12  d 1.3    10

Итак, в этом примере для каждой строки я добавляю столбец с именем value, который имеет все три значения в пределах c(0,5,10)

Этот код не идеален, потому что фактическая последовательность, которую я хочу, в значительной степени 1:70, и я не хочу писать все 70 новых переменных в моем mutate вручную. Конечно, есть лучший способ сделать это, вы можете мне помочь?

Мне не нужно оставаться в dplyr, но я хочу, чтобы я не мог передать свой код.

Спасибо

Ответы [ 6 ]

4 голосов
/ 20 марта 2019
library(tidyr)
dd %>% crossing(value = c(0, 5, 10))
   id  v1 value
1   a 0.3     0
2   a 0.3     5
3   a 0.3    10
4   b 0.1     0
5   b 0.1     5
6   b 0.1    10
7   c 0.7     0
8   c 0.7     5
9   c 0.7    10
10  d 1.3     0
11  d 1.3     5
12  d 1.3    10
3 голосов
/ 20 марта 2019

Один из вариантов - добавить значения в фрейм данных и сделать merge в базе R.

merge(dd, data.frame(value = c(0, 5, 10)))

#   id  v1 value
#1   a 0.3     0
#2   b 0.1     0
#3   c 0.7     0
#4   d 1.3     0
#5   a 0.3     5
#6   b 0.1     5
#7   c 0.7     5
#8   d 1.3     5
#9   a 0.3    10
#10  b 0.1    10
#11  c 0.7    10
#12  d 1.3    10
2 голосов
/ 20 марта 2019

С data.table:

setDT(dd)[, .(value = c(0, 5, 10)), by = .(id, v1)]

Выход:

    id  v1 value
 1:  a 0.3     0
 2:  a 0.3     5
 3:  a 0.3    10
 4:  b 0.1     0
 5:  b 0.1     5
 6:  b 0.1    10
 7:  c 0.7     0
 8:  c 0.7     5
 9:  c 0.7    10
10:  d 1.3     0
11:  d 1.3     5
12:  d 1.3    10

Если вы загрузите magrittr (или если у вас уже загружено dplyr или tidyverse), вы можете продолжить с трубами setDT(dd)[, .(value = c(0, 5, 10)), by = .(id, v1)] %>% ...

1 голос
/ 20 марта 2019

Вступление в партию с пакетом splitstackshape,

library(splitstackshape)

transform(expandRows(dd, count = 3, count.is.col = FALSE), value = c(0, 5, 10))

#    id  v1 value
#1    a 0.3     0
#1.1  a 0.3     5
#1.2  a 0.3    10
#2    b 0.1     0
#2.1  b 0.1     5
#2.2  b 0.1    10
#3    c 0.7     0
#3.1  c 0.7     5
#3.2  c 0.7    10
#4    d 1.3     0
#4.1  d 1.3     5
#4.2  d 1.3    10
1 голос
/ 20 марта 2019

Решение с использованием lapply, очень мощного инструмента:

dd <- data.frame(id = letters[1:4], v1 = c(0.3,0.1,0.7,1.3))
newdf<- lapply(c(0,5,10), function(value) {
   cbind(dd, data.frame(value=rep(value,NROW(dd))))
})
newdf <- do.call('rbind',newdf)

#    id  v1 value
#1   a 0.3     0
#2   b 0.1     0
#3   c 0.7     0
#4   d 1.3     0
#5   a 0.3     5
#6   b 0.1     5
#7   c 0.7     5
#8   d 1.3     5
#9   a 0.3    10
#10  b 0.1    10
#11  c 0.7    10
#12  d 1.3    10
1 голос
/ 20 марта 2019

Мы также можем использовать expand из пакета tidyr.

library(tidyverse)

dd <- data.frame(id = letters[1:4], v1 = c(0.3,0.1,0.7,1.3))

dd %>% 
  expand(nesting(id, v1), value = seq(0, 10, by = 5)) %>%
  arrange(value, id)
# # A tibble: 12 x 3
#    id       v1 value
#    <fct> <dbl> <dbl>
#  1 a       0.3     0
#  2 b       0.1     0
#  3 c       0.7     0
#  4 d       1.3     0
#  5 a       0.3     5
#  6 b       0.1     5
#  7 c       0.7     5
#  8 d       1.3     5
#  9 a       0.3    10
# 10 b       0.1    10
# 11 c       0.7    10
# 12 d       1.3    10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...