Как воспроизвести цикл «для», чтобы заполнить фрейм данных из другого фрейма данных с помощью «dplyr»? - PullRequest
0 голосов
/ 06 октября 2018

Я ищу быстрый способ заполнить фрейм данных из другого фрейма данных.Для этого я бы хотел использовать пакет dplyr.Например, рассмотрим следующий код, который заменяет NA в dt2 из dt1.Моя цель - избежать цикла for.

set.seed(123)
  dt1 <- data.frame(ID = c(104, 109, 111, 121), a = c(1, 8, 5, 9), b = c(100, 220, 877, 120), c = c(1, 3, 2, 3))
  ## print(dt1)
  dt2 <- data.frame(ID = c(rep(104, 1), rep(109, 3), rep(111, 2), rep(121, 3)), 
                    a = c(rep(NA, 1), rep(NA, 3), rep(NA, 2), rep(NA, 3)),
                    b = c(rep(NA, 1), rep(NA, 3), rep(NA, 2), rep(NA, 3)))
  ## print(dt2)

  for(i in as.vector(dt1[,c("ID")])) {

    dt2[dt2[, c("ID")] %in% i, c("a")] <- sample(0:dt1[dt1[, c("ID")] == i, c("a")], size = dt1[dt1[, c("ID")] == i, c("c")], replace = T)
    dt2[dt2[, c("ID")] %in% i, c("b")] <- sample(0:dt1[dt1[, c("ID")] == i, c("b")], size = dt1[dt1[, c("ID")] == i, c("c")], replace = T)

  }
  print(dt2)

Вывод:

>   print(dt2)
   ID a   b
1 104 0  79
2 109 3  10
3 109 7 116
4 109 8 197
5 111 3 840
6 111 2 398
7 121 6 108
8 121 5  29
9 121 1   5

Вот мой первый тест с использованием пакета dplyr:

  set.seed(123)
  dt1 <- data.frame(ID = c(104, 109, 111, 121), a = c(1, 8, 5, 9), b = c(100, 220, 877, 120), c = c(1, 3, 2, 3))
  ## print(dt1)
  dt2 <- data.frame(ID = c(rep(104, 1), rep(109, 3), rep(111, 2), rep(121, 3)), 
                    a = c(rep(NA, 1), rep(NA, 3), rep(NA, 2), rep(NA, 3)),
                    b = c(rep(NA, 1), rep(NA, 3), rep(NA, 2), rep(NA, 3)))
  i <- 104
  test <- dt2 %>%
    mutate(a = replace(a, ID == i, sample(0:dt1[dt1[, c("ID")] == i, c("a")], size = dt1[dt1[, c("ID")] == i, c("c")], replace = T)),
           b = replace(b, ID == i, sample(0:dt1[dt1[, c("ID")] == i, c("b")], size = dt1[dt1[, c("ID")] == i, c("c")], replace = T)))
  print(test)

Однако я не знаю, как считать цикл на ID, i.e., with i = 104, i = 109, i = 111, and i = 121

1 Ответ

0 голосов
/ 06 октября 2018

Мы можем сделать это, используя left_join с 'dt1' по 'ID', затем сгруппированные по 'ID', transmute столбцы 'a' и 'b'

left_join(dt2[1], dt1, by = "ID") %>%
    group_by(ID) %>% 
    transmute(a = sample(0:a[1], size = c[1], replace = TRUE),
              b = sample(0:b[1], size = c[1], replace = TRUE))

Это также можно сделать из 'df1'

dt1 %>%
    rowwise() %>%
    mutate_at(vars(a, b), funs(list(sample(0:., size = c, replace = TRUE)))) %>%
    unnest %>%
    select(-c)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...