Для кадров данных, уже находящихся в «длинном» формате, как можно сделать измеряемую переменную переменной ID без транспонирования всего кадра данных? - PullRequest
0 голосов
/ 31 декабря 2018

Я звоню в базу данных, используя пакет (brapi), который возвращает необходимые данные в длинном формате.API обрабатывает определенные переменные идентификатора как измеренные переменные, что проблематично, потому что мои сценарии анализа нуждаются в них как переменные идентификатора.Я не могу изменить вызов к базе данных таким образом, чтобы он сделал это для меня, и я не хочу просто reshape2::cast, а затем растопить всю эту вещь, потому что есть сотни переменных, которые делают это дорогостоящим.В идеале я ищу способ сделать это с помощью reshape2, plyr и т. П.

Моя проблема может быть замечена с использованием встроенного фрейма данных mtcars.Представьте, что вы получаете длинный фрейм данных, meltedcars, с шестерней в качестве переменной-идентификатора из базы данных, но вы также хотите cyl в качестве переменной-идентификатора.Я пробовал очевидные dcast команды (например, показанные ниже), но я знал, что это не сработает, потому что функция не найдет cyl в качестве переменной.

meltedcars<-melt(mtcars, id.vars = c("gear"))

head(meltedcars)

   gear variable value
1    4      mpg  21.0
2    4      mpg  21.0
3    4      mpg  22.8
4    3      mpg  21.4
5    3      mpg  18.7
6    3      mpg  18.1

c<-dcast(d, gear + cyl ~ variable, value.var= "value")
Error in FUN(X[[i]], ...) : object 'cyl' not found

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

РЕДАКТИРОВАТЬ

Я должен быть яснее.Для целей данного поста столбцы идентификаторов - это переменные в длинном формате, которые используются для идентификации наблюдаемого объекта, а не того, что измерялось.Допустим, мы измеряли mpg и disp на всех автомобилях в фрейме данных mtcars, и мы хотели дополнительные , идентифицирующие информацию об автомобиле, кроме названия модели в фрейме данных в виде собственного столбца.,Чтобы идентифицировать автомобиль, у вас есть столбец с именами автомобилей (я настроил mtcars так, чтобы имена строк теперь были столбцом внутри mtcars с именем model), столбцом того, чем они являются gear, и одним для сколькихcyl каждая машина имеет.Затем у нас есть столбец переменной и столбец значений, где вид наблюдения и его значение указаны соответственно.Когда я делаю вызов в базу данных, это то, что я получаю:

head (mtcarsFromDB)

               model gear variable value
1         Mazda RX4    4      mpg  21.0
2     Mazda RX4 Wag    4      mpg  21.0
3        Datsun 710    4      mpg  22.8
4    Hornet 4 Drive    3      mpg  21.4
5 Hornet Sportabout    3      mpg  18.7
6           Valiant    3      mpg  18.1

Но я хочу переформатировать этот df с cyl, который в настоящее время является значениемпеременной, как столбец идентификатора типа gear без приведения и плавления всей вещи.Это должно выглядеть так:

              model gear cyl variable value
1         Mazda RX4    4   6      mpg  21.0
2     Mazda RX4 Wag    4   6      mpg  21.0
3        Datsun 710    4   4      mpg  22.8
4    Hornet 4 Drive    3   6      mpg  21.4 
5 Hornet Sportabout    3   8      mpg  18.7
6           Valiant    3   6      mpg  18.1

Ответы [ 2 ]

0 голосов
/ 01 января 2019

Я создаю тот же набор данных, что и при редактировании.

# prepare data
cars <- mtcars
cars$model <- row.names(cars)
row.names(cars) <- seq_along(cars$mpg)

df <- melt(cars, id.vars = c("model", "gear"))

Теперь я задаю df для наблюдений "cyl" и повторяю его 9 раз, чтобы соответствовать расплавленному фрейму данных.Что дает мне столбец «цил» с его значениями в длинном формате, повторяемыми 9 раз, что согласуется с порядком из расплавленного df.

df1 <- df[df$variable == "cyl", ]
names(df1)[4] <- "cyl" 
df1$variable <- NULL

df <- df[df$variable != "cyl", ]

# replicate data frame 9 times
df2 <- do.call("rbind", replicate(9, df1, simplify = FALSE))

Просто добавьте новый столбец в фрейм данных из начальной точки.

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

0 голосов
/ 31 декабря 2018

Я повторю проблему, используя ваш подход использования mtcars:

df <- head(mtcars) # get a small chunk to work with

df <- df %>% 
  mutate(id = paste0("id", row_number())) # create an id variable

# use tidyr::gather() to "melt" the data:
df_long <- df %>%
  gather()

На данный момент df_long должен быть в формате «проблемы», который вы указали.

# Here's the problem area. Focus in on the last '10':
df_long %>% tail(10)

    key value
63 carb     1
64 carb     1
65 carb     2
66 carb     1
67   id   id1
68   id   id2
69   id   id3
70   id   id4
71   id   id5
72   id   id6

Итак, id смешаны. Я предполагаю, что это ваша проблема?Следующее не очень элегантно, но работает:

# get the id strings, store in `ids`
ids <- df_long %>%
  filter(key == "id") %>%
  select(value) %>%
  .[[1]]

Теперь, повторите идентификаторы для всех строк и, наконец, удалите исходные строки идентификаторов в tail выше:

df_long <- df_long %>%
  mutate(newid = rep(ids, length(unique(.$key)))) %>%
  filter(key != "id") %>%
  select(newid, key, value)

head(df_long)

Результат:

  newid key value
1   id1 mpg    21
2   id2 mpg    21
3   id3 mpg  22.8
4   id4 mpg  21.4
5   id5 mpg  18.7
6   id6 mpg  18.1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...