Создайте новый фрейм данных на основе значения строки и скопируйте его - PullRequest
0 голосов
/ 11 октября 2019

Предположим, у меня есть этот фрейм данных:

df <- data.frame(town = c("town1","town2","town3"),
             totpop = c(1700, 1500, 1200),
             groupAreceived = c(10, 5, 2),
             groupBreceived = c(9, 4, 1),
             groupCreceived = c(8, 3, 0))

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

df
   town totpop groupAreceived groupBreceived groupCreceived
1 town1   1700             10              9              8
2 town2   1500              5              4              3
3 town3   1200              2              1              0

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

Я могу сделать это вручную для одного города:

town1.a <- data.frame(matrix(ncol = 4, nrow = df$totpop[[1]]))
x <- c("totpop", "group", "received", "town")
colnames(town1.a) <- x

totpop <- c(rep(1, df$totpop[[1]]))
group <- c(rep("A", df$totpop[[1]]))
received <- c(rep(df$groupAreceived[[1]], df$totpop[[1]]))
town <- c(rep("Town1", df$totpop[[1]]))

town1.a$totpop <- totpop
town1.a$group <- group
town1.a$received <- received
town1.a$town <- town

 head(town1.a)
  totpop group received  town
1      1     A       10 Town1
2      1     A       10 Town1
3      1     A       10 Town1
4      1     A       10 Town1
5      1     A       10 Town1
6      1     A       10 Town1

Этот фрейм данных будет иметь 1700 строк.

Какможно ли автоматизировать этот код / ​​использовать его в цикле for, чтобы он делал то же самое, но для каждой группы?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 11 октября 2019

В базе R вы можете использовать reshape для преобразования в длинный формат и затем реплицировать строки.

long_df <- reshape(df, direction = "long", idvar = c("town", "totpop"), 
            varying = list(names(df)[3:5]), v.names = "Group")
output <- long_df[rep(seq_len(nrow(long_df)), long_df$totpop), ]
row.names(output) <- NULL
head(output)

#   town totpop time Group
#1 town1   1700    1    10
#2 town1   1700    1    10
#3 town1   1700    1    10
#4 town1   1700    1    10
#5 town1   1700    1    10
#6 town1   1700    1    10
0 голосов
/ 11 октября 2019
library(tidyverse)
df %>%
  # Reshape into longer form
  pivot_longer(cols = -c(town, totpop), names_to = "group", values_to = "received") %>%
  # remove "group" and "received" from the group column
  mutate(group = group %>% str_remove_all("group|received")) %>%
  # make as many copies of each row as "totpop"
  uncount(totpop) %>%
  mutate(totpop = 1)

# A tibble: 13,200 x 4
   town  group received totpop
   <fct> <chr>    <dbl>  <dbl>
 1 town1 A           10      1
 2 town1 A           10      1
 3 town1 A           10      1
 4 town1 A           10      1
 5 town1 A           10      1
 6 town1 A           10      1
 7 town1 A           10      1
 8 town1 A           10      1
 9 town1 A           10      1
10 town1 A           10      1
# ... with 13,190 more rows

Вывод здесь имеет 13 200 строк, что соответствует (1700 + 1500 + 1200) в totpop, умноженному на три столбца.

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