Разделите уровни факторов в одном столбце, чтобы получить новый фрейм данных - PullRequest
0 голосов
/ 16 июня 2019

У меня есть фрейм данных, который выглядит как следующий пример (здесь есть фрейм данных, содержащий две симуляции для каждого раунда, состояния и лечения):

df <- data.frame(Sim=c(1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2),Round=c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2),Condition=c('A1','A1','A2','A2','A1','A1','A2','A2','B1','B1','B2','B2','B1','B1','B2','B2','A1','A1','A2','A2','A1','A1','A2','A2','B1','B1','B2','B2','B1','B1','B2','B2'),Treatment=c(1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,2,2,2,2),Output=c(3,2.5,2.1,1.9,2.8,2.3,2.0,1.6,2.6,2.7,1.3,1.2,2.4,2.3,1,1.1,2,1.3,1.3,0.9,2,2.1,2.1,1.2,2,1.7,1.2,1,2,1.3,0.5,0.4))

Состояние охватывает четыре уровня: A1, A2, B1, B2.

Теперь я хотел бы манипулировать этим фреймом данных, чтобы получить Выход уменьшение (%), которое A2 производит на A1 (1- (A2 / A1) для каждого моделирования, раунда, условия и лечение. То же самое для B2 на B1 (1- (B2 / B1).

Мы должны получить новый dtaframe, похожий на этот («Новый вывод» здесь не основан на dataframe):

Round    New condition  Treatment   Newoutput
1        1-(A2/A1)      1           0.3
1        1-(A2/A1)      1           0.24
...
1        1-(B2/B1)      2           0.5
1        1-(B2/B1)      2           0.56
...
2        1-(A2/A1)      1           0.43
2        1-(A2/A1)      1           0.23
...
2        1-(B2/B1)      1           0.4
2        1-(B2/B1)      1           0.5
...

Я пытался split исходный фрейм данных, но не уверен, как я мог тогда работать с ним. Я также пытался работать непосредственно над фреймом данных, используя transform. Пока безуспешно.

Заранее спасибо за любую помощь.

1 Ответ

1 голос
/ 16 июня 2019

Сначала мы можем split Output на Condition, затем выбрать значения 1 и 2 поочередно и применить формулу для каждого из них, используя mapply

lst <- with(df, split(Output, Condition))
mapply(function(x, y) 1-(y/x), lst[c(TRUE, FALSE)], lst[c(FALSE, TRUE)])

#             A1        B1
#[1,]  0.3000000 0.5000000
#[2,]  0.2400000 0.5555556
#[3,]  0.2857143 0.5833333
#[4,]  0.3043478 0.5217391
#[5,]  0.3500000 0.4000000
#[6,]  0.3076923 0.4117647
#[7,] -0.0500000 0.7500000
#[8,]  0.4285714 0.6923077

Иливозможно, напрямую, если вы хотите, чтобы они представляли собой один векторуровни не являются фиксированными, его можно переставить вручную

df <- df[order(match(df$Condition, c("A1", "A2", "B1", "B2", "C1", "C2"))), ]

Если есть еще много уровней, вы можете сделать

df <- df[order(match(df$Condition, paste0(rep(LETTERS[1:3],each = 2), rep(1:2, 3)))), ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...