У меня есть следующий фрейм данных:
df <- data.frame(
var1 = c("A", "C", "C", "B", "D"),
val1 = c(.89, .99, .67, .88, .92),
var2 = c("B", "A", "D", "A", "B"),
val2 = c(.87, .95, .55, .84, .88),
var3 = c("C", "B", "B", "C", "A"),
val3 = c(.66, .55, .45, .81, .77),
var4 = c("D", "D", "A", "D", "C"),
val4 = c(.44, .33, .43, .77, .69),
stringsAsFactors = FALSE
)
df
# var1 val1 var2 val2 var3 val3 var4 val4
#1 A 0.89 B 0.87 C 0.66 D 0.44
#2 C 0.99 A 0.95 B 0.55 D 0.33
#3 C 0.67 D 0.55 B 0.45 A 0.43
#4 B 0.88 A 0.84 C 0.81 D 0.77
#5 D 0.92 B 0.88 A 0.77 C 0.69
Я пытаюсь сделать следующее: если var1
равно C
или D
, то я хочу заменить var1
на A
и val1
с соответствующим значением A
.Кроме того, для строк, которые удовлетворяют этому условию, я хочу, чтобы var2
, var3
и var4
, а также val2
, val3
и val4
сохранили свой первоначальный порядок.Ниже мой ожидаемый результат:
# var1 val1 var2 val2 var3 val3 var4 val4
#1 A 0.89 B 0.87 C 0.66 D 0.44
#2 A 0.95 C 0.99 B 0.55 D 0.33
#3 A 0.43 C 0.67 D 0.55 B 0.45
#4 B 0.88 A 0.84 C 0.81 D 0.77
#5 A 0.77 D 0.92 B 0.88 C 0.69
Строка vals
в моем исходном наборе данных всегда будет в порядке убывания (то есть val1
> val2
> val3
> val4
), икаждая буква будет в строке ровно один раз.
Мне удалось получить ожидаемый результат с довольно громоздким циклом for
:
df_new <- df
for (i in 1:nrow(df)){
if (df$var1[i] %in% c("C", "D")){
if (df$var2[i] == "A"){
df_new$var1[i] <- df$var2[i]
df_new$var2[i] <- df$var1[i]
df_new$val1[i] <- df$val2[i]
df_new$val2[i] <- df$val1[i]
} else if (df$var3[i] == "A"){
df_new$var1[i] <- df$var3[i]
df_new$var2[i] <- df$var1[i]
df_new$var3[i] <- df$var2[i]
df_new$val1[i] <- df$val3[i]
df_new$val2[i] <- df$val1[i]
df_new$val3[i] <- df$val2[i]
} else {
df_new$var1[i] <- df$var4[i]
df_new$var2[i] <- df$var1[i]
df_new$var3[i] <- df$var2[i]
df_new$var4[i] <- df$var3[i]
df_new$val1[i] <- df$val4[i]
df_new$val2[i] <- df$val1[i]
df_new$val3[i] <- df$val2[i]
df_new$val4[i] <- df$val3[i]
}
}
}
, но я надеюсь, что более элегантный(идеально векторизованное) решение существует.