Воссоздание кадра данных с использованием условий из двух разных столбцов - PullRequest
2 голосов
/ 29 апреля 2019

У меня массивный фрейм данных выглядит так:

df = data.frame(year = c(rep(1998,5),rep(1999,5)), 
                  loc = c(10,rep(14,4),rep(10,2),rep(14,3)),
                  sitA = c(rep(0,3),1,1,0,1,0,1,1),
                  sitB = c(1,0,1,0,1,rep(0,4),1),
                  n = c(2,13,2,9,4,7,2,7,7,4))
df
   year loc sitA sitB  n
1  1998  10    0    1  2
2  1998  14    0    0 13
3  1998  14    0    1  2
4  1998  14    1    0  9
5  1998  14    1    1  4
6  1999  10    0    0  7
7  1999  10    1    0  2
8  1999  14    0    0  7
9  1999  14    1    0  7
10 1999  14    1    1  4 

Как видите, существуют годы, населенные пункты, две разные ситуации (обозначенные как sitA и sitB) и, наконец, количество этих записей (столбец n).

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

df.new
  year loc sitB.0.sitA.0 sitB.0.sitA.1 sitB.1.sitA.0 sitB.1.sitA.1
1 1998  10             0             0             2             0
2 1998  14            13             9             2             4
3 1999  10             7             2             0             0
4 1999  14             7             7             0             4

Самая сложная часть, которую вы можете понять, состоит в том, что исходный кадр данных не включает в себя все условия. У него есть только те, у которых число больше 0. Таким образом, новый фрейм данных должен иметь «0» для отсутствующих условий в оригинальном фрейме данных. Поэтому хорошо известные функции, такие как плавление (изменение формы) или заполнение, не смогли решить мою проблему. Небольшая помощь будет оценена.

1 Ответ

3 голосов
/ 29 апреля 2019

A tidyverse метод, мы сначала добавляем имена столбцов к значениям для sit.. столбцов.Затем мы unite и объединяем их в один столбец и, наконец, spread значения.

library(tidyverse) 
df[3:4] <- lapply(names(df)[3:4], function(x) paste(x, df[, x], sep = "."))

df %>%
  unite(key, sitA, sitB, sep = ".") %>%
  spread(key, n, fill = 0)

#  year loc sitA.0.sitB.0 sitA.0.sitB.1 sitA.1.sitB.0 sitA.1.sitB.1
#1 1998  10             0             2             0             0
#2 1998  14            13             2             9             4
#3 1999  10             7             0             2             0
#4 1999  14             7             0             7             4

Если положение столбцов не фиксировано, вы можете использовать grep first

cols <- grep("^sit", names(df))
df[cols] <- lapply(names(df)[cols], function(x) paste(x, df[, x], sep = "."))
...