2015-12-27 81 views
3

我想刪除value>b>,但我不確定如何操作。根據條件刪除熔化數據

的樣本數據:

df <- data.frame(day = c(1, 1, 2, 2, 3, 3), var = c("a", "b", "a", "b", "a", "b"), value = c(1, 2, 3, 3, 2, 1) 

輸出:

day var value 
1 1 a  1 
2 1 b  2 
3 2 a  3 
4 2 b  3 
5 3 a  2 
6 3 b  1 

所需的輸出:

day var value 
1 1 a  1 
2 1 b  2 
+0

是否有原因,你不想從長切換到寬?通過dcast或tidyr? – Shape

+0

@Shape主要是因爲代碼效率。 – Vedda

回答

3

這裏是爲了避免打算從長到寬data.table解決方案:

dt <- data.table(df) 
dt[,if(value[var == 'a'] >= value[var == 'b']) .SD,by = day] 

編輯:我現在認識到所需輸出不適合你最初的不平等,所以調整不平等匹配:)

EDIT2:如果你不想做的data.table,那麼這裏的dplyr解決方案

df %>% group_by(day) %>% filter(value[var == 'a'] >= value[var == 'b']) 

EDIT3:如果你想要把NA在那麼這個

df %>% group_by(day) %>% mutate(value = if(value[var == 'a'] >= value[var == 'b']) as.numeric(NA) else value) 

EDIT4:注意這最後的解決方案似乎露出了一個bug,其中NA的是奇怪的處理,在這裏看到:Why is dplyr removing values not met by condition?

+0

謝謝,但由於我正在使用的腳本的性質,我寧願不使用'data.table'。我有所有我的'data.frames'成'data.tables',這是一個額外的步驟,會減慢我的代碼 – Vedda

+0

看到編輯,我翻譯轉換成dplyr – Shape

+0

謝謝!這將工作。如果不是刪除,我只想將「NA」放在行中? – Vedda

3

Shape的答案是解決您的問題的正確方法。
爲了擴展Shape的答案,我想用一個更通用的解決方案做出貢獻。
eav函數包dwtools旨在通過更簡單的度量計算來解決Entity-attribute-value數據結構。功能定義如下,你不需要dwtools包。
它爲每個組計算rm變量。計算公式可以與引用j參數[.data.table在融化EAV之後以及在再次轉換爲EAV之前的調用相同。

library(data.table) 
eav = function(x, j, id.vars = key(x)[-length(key(x))], variable.name = key(x)[length(key(x))], measure.vars = names(x)[!(names(x) %in% key(x))], fun.aggregate = sum, shift.on = character(), wide=FALSE){ 
    stopifnot(is.data.table(x)) 
    r <- x[,lapply(.SD,fun.aggregate),c(id.vars,variable.name),.SDcols=measure.vars 
      ][,dcast(.SD,formula=as.formula(paste(paste(id.vars,collapse=' + '),paste(variable.name,collapse=' + '),sep=' ~ ')),fun.aggregate=fun.aggregate,value.var=measure.vars) 
      ][,eval(j), by = eval(id.vars[!(id.vars %in% shift.on)]) 
       ] 
    if(wide) r[] else melt(r,id.vars=id.vars, variable.name=variable.name, value.name=measure.vars)[,.SD,keyby=c(id.vars,variable.name)] 
} 

df = data.frame(day = c(1, 1, 2, 2, 3, 3), var = c("a", "b", "a", "b", "a", "b"), value = c(1, 2, 3, 3, 2, 1)) 
dt = as.data.table(df) 
setkey(dt, day, var) 
r = eav(dt, quote(rm := as.numeric(a >= b))) 
print(r) 
# day var value 
#1: 1 a  1 
#2: 1 b  2 
#3: 1 rm  0 
#4: 2 a  3 
#5: 2 b  3 
#6: 2 rm  1 
#7: 3 a  2 
#8: 3 b  1 
#9: 3 rm  1 
r[, if(value[var=="rm"] == 0) .SD, by = day 
    ][var!="rm"] # you need to exclude temporary variable 
# day var value 
#1: 1 a  1 
#2: 1 b  2 

該解決方案還可能慢於形的(你可以填充你的大數據,因此它可以被測量的樣品),但可能是複雜的計算更容易在EAV很多措施,並且支持換班 - 見eav examples