2014-01-23 4 views
3

мой dataframe:вычесть два столбца в dataframe, если выполняется условие

Dead4 Dead5 
0  0 
0  0 
0  0 
1  2 
0  0 
0  0 
1  2 
0  0 
1  0 
0  1 
1  1 
5  10 

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

indices<- (t$Dead5 > t$Dead4) 
t$Dead6[indices]<- (t$Dead6) - (t$Dead5) 


Warning message: 
In t$Dead6[indices] <- (t$Dead6) - (t$Dead5) : 
    number of items to replace is not a multiple of replacement length 

Может кто-нибудь объяснить, что я делаю неправильно, и помочь мне написать несколько строк кода, которые сделают это?

ответ

4

Вы можете сделать это:

indices <- (t$Dead5 > t$Dead4) # indices is a logical vector with TRUE and FALSE 

t$Dead5[indices] <- (t$Dead5 - t$Dead4)[indices] 

Это также справедливо и для любой другой операции с вашим data.frame, как:

t$Dead6[indices] <- (t$Dead6 - t$Dead5)[indices] 

Если столбец Dead6 существует. С каждой стороны берутся только значения, где indices - TRUE, поэтому заменяемые и замененные значения имеют одинаковую длину, и вы не получите предупреждение.

Что вы делали неправильно это вы давали в качестве замены полный (t$Dead5 - t$Dead4) вектор, который больше, чем количество раз indices является TRUE (замененные значения в левом).

R использовал только первые значения вашего вектора замены и дал вам предупреждение.

+0

спасибо для объяснения. Сейчас это делает много смысла. – Chad

1

Использование data.table

library(data.table) 
DT <- as.data.table(DF) 

DT[Dead5 > Dead4, Dead5 := Dead5 - Dead4] 

Вы также можете сделать это в base R с помощью within или transform

2

transform() Использование и ifelse():

transform(t, Dead5 = ifelse(Dead5 > Dead4, Dead5-Dead4, Dead5)) 
+0

это умный. Спасибо alot – Chad

0

Другой подход без ifelse и без индексации:

indices <- t$Dead5 > t$Dead4 
t$Dead6 <- t$Dead6 - (t$Dead5 * indices) 
Смежные вопросы