#r #dataframe #tidyverse #reshape #tibble
#r #фрейм данных #tidyverse #изменить форму #tibble
Вопрос:
У меня есть небольшой вопрос, связанный с изменением формы моего фрейма данных, где у меня есть данные ID «grouped_by». У меня есть следующая схема df ( 2 примерных экземпляра, которые я хочу расширить (всего у меня > 5000)):
id solver scoreA scoreB group size
<chr> <chr> <dbl> <dbl> <chr> <dbl>
1 instance_1 s1 1 0.5 g1 1000
2 instance_1 s2 100 50 g1 1000
… что я хочу получить, так это:
id solver.best scoreA.s1 scoreA.s2 scoreB.s1 scoreB.s2 group size
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl>
1 instance_1 s1 1 100 0.5 50 g1 1000
Ценю вашу помощь.
BR
Комментарии:
1. Если у вас более 5000 строк, и вы хотите сделать это — у вас будет около 5000 столбцов, это почти наверняка неправильный путь. То, чего вы пытаетесь достичь, должно иметь альтернативный маршрут.
2. идентификатор всегда группирует 2 экземпляра … в основном говоря, что я хочу, чтобы две строки стали плоскими. т. Е. увеличились с 5000 строк до 2500
3. Вы можете посчитать, в чем разница между 5 x 5000 и 2500 x 5000?
4. Я не понимаю вашу точку зрения. Я признаю, что распространение с помощью методов tidyverse может не привести к желаемому результату, и без группировки он будет иметь размер 2500 x 5000 df. Кроме этого, я не вижу никакой фатальности в идее сжать 2 строки в одну, сгруппированную по идентификатору…
5. Цель просьбы вас поделиться
dput
заключается в том, что мы можем скопировать ваши данные (или их часть) в нашу среду R и использовать их. Когда вы обновляете свой пост неполнымdput
(который мы не можем скопировать), это все равно что вообще не делиться. Если ваши данные очень большие, вы можете использовать только первые несколько строк, напримерdput(head(df))
, для первых 6 строк.
Ответ №1:
Возможно, вы можете попробовать приведенный ниже код
reshape(within(df, Q <- ave(seq(nrow(df)), id, FUN = seq_along)),
direction = "wide",
idvar = "id",
timevar = "Q"
)
что дает
> reshape(cbind(df,Q = seq(nrow(df))),direction = "wide",idvar = "id",timevar = "Q")
id solver.1 scoreA.1 scoreB.1 group.1 size.1 solver.2 scoreA.2
1 instance 1 s1 1 0.5 g1 1000 s2 100
scoreB.2 group.2 size.2
1 50 g1 1000
Данные
> dput(df)
structure(list(id = c("instance 1", "instance 1"), solver = c("s1",
"s2"), scoreA = c(1L, 100L), scoreB = c(0.5, 50), group = c("g1",
"g1"), size = c(1000L, 1000L)), class = "data.frame", row.names = c("1",
"2"))
Комментарии:
1. спасибо, но для меня это возвращает только значения NA :/…. У меня больше, чем всего на 2 строки. Но всегда есть 2 экземпляра с идентификатором groubed_by…
2. @gero Вы использовали данные в моем ответе? В противном случае, пожалуйста,
dput()
ваши данные, тогда я посмотрю, что произошло3. структура (список(идентификатор = c («экземпляр 1», «экземпляр 1», «экземпляр 2», «экземпляр 2», [… другие экземпляры / группы …], решатель = c («S1», «S2», [… больше решателя …], scoreA = c(3.3818, 358.1937, …., scoreB = c(1.3818, 100.1937, …., group = c(«g1», «g1», …., size = c(«1000», «1000», ….)
4. @gero Не могли бы вы поместить свои данные в свой пост? Похоже, данные, которые вы указали в комментарии, не являются полными
5. Данные конфиденциальны. Однако, вот все из dput() (найти в отредактированном сообщении)
Ответ №2:
Поскольку я все еще хочу иметь удобный, например, tidyverse, передовой опыт, я все еще хочу поделиться практическим подходом, который концептуально работает так же хорошо :):
# create empty (wide) target df
wide_df <- data.frame(matrix(ncol = 8, nrow = 0))
names <- c("id", "best_solver", "scoreA_s1", "scoreA_s2",
"scoreB_s1", "scoreB_s2", "group", "size")
colnames(wide_df) <- names
# traverse grouped by and arranged original (long) df
for(i in seq(2, length(long_df$group), by = 2)){
wide_df[i/2, "id"] <- long_df[i, "id"]
wide_df[i/2, "best_solver"] <- long_df[which(long_df[(i-1):i, "scoreA"] ==
min(long_df[i-1, "scoreA"], long_df[i, "scoreA"])),
"solver"]
wide_df[i/2, "scoreA_s1"] <- long_df[i-1, "scoreA"]
wide_df[i/2, "scoreA_s2"] <- long_df[i, "scoreA"]
wide_df[i/2, "scoreB_s1"] <- long_df[i-1, "scoreB"]
wide_df[i/2, "scoreB_s2"] <- long_df[i, "scoreB"]
wide_df[i/2, "group"] <- long_df[i, "group"]
wide_df[i/2, "size"] <- long_df[i, "size"]
}