2012-06-06 38 views
0

我有一個大型數據框,有48列,我想在數據框的每一行上運行一個函數,通過測試的列該功能被設置爲NA。這個測試涉及從另一個數據框中獲取一個數字。 adply對此很自然,但我在解決問題時遇到了問題,無法提供我想要的結果。根據來自數據幀中其他列的測試將NA設置爲列

讓我澄清:

這是我要處理的數據幀的例子:

>df 
    pt depth Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir 
1 1 0.1   NA   NA   NA   NA 
2 2 0.2   NA   NA  1.344  324.0 
3 3 0.3   NA   NA  0.445  167.0 
4 4 0.4  1.455  354.2  0.322  321.2 

這裏是小數據幀從該測試將得到:

> tcell 
    depth name 
1 0.2 Cell1 
2 0.4 Cell2 
3 0.6 Cell3 
4 0.8 Cell4 

整個想法是爲那些比大數據框中列出的實際深度更深的單元數據點指定NA(即在第3行深度爲0.3,但有兩個數據點對應於Cell2,深度爲0.4米,因此這些是錯誤。我想NA這些)。

我想編寫一個函數,它在同一時間發生在一排: 1)抓住儀器深度 2)獲取列名 3)獲取比儀器更深層細胞的指數列表深度 4)獲取這些單元格的名稱(即Cell1,Cell2,Cell4等) 5)使用正則表達式在列名稱列表中找到具有相應單元格的列(即Cell1_avgdir,Cell1_avgvel等) ) 6)使用這些索引,將這些列值設置爲NA。

這是我到目前爲止有:

depthNA = function(x) { 
    depth = x$depth 
    nms = names(df) 
    ind = as.character(which(depth < tcell$depth)) 
    c = tcell$name[ind] 
    patt = paste(c,collapse="|") 
    c_ind = grep(patt,nms) 
    x[,c_ind] <- NA 
} 

adply(df,1,depthNA) 

不幸的是這並沒有做什麼,我想的那樣,現在我卡試圖找出原因。

它給了我這樣的:

當我要的是:

pt depth Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir 
1 1 0.1   NA   NA   NA   NA 
2 2 0.2   NA   NA   NA   NA 
3 3 0.3   NA   NA   NA   NA 
4 4 0.4  1.455  354.2  0.322  321.2 

希望我有充分的解釋我的問題。感謝任何能夠:1)解決我開始的任務,或者2)告訴我一個更好的方式來做到這一點,我不知道。

-SH

+0

在你的最後一排,爲什麼不爲'Cell1_avgvel,Cell1_avgdir和Cell2_avgdir值'設置爲NA? 'tcell'中Cell1的深度爲0.2,Cell2的值爲0.4 ... 321.2大於0.4 – Chase

+0

在最後一行中,由於深度爲0.4,因此所有數據都是有效的。這意味着單元格1和單元格2(以及與它們關聯的所有列)都在該深度內(根據查找表)。 – svh160

回答

1

以下是回答你的想法概括的話,但你的輸出不匹配的答案。請參閱我上面關於輸出是否正確的評論。答案依賴於reshape2使加入更容易。

首先,我在讀你的數據:

df <- read.table(text = " pt depth Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir 
1 1 0.1   NA   NA   NA   NA 
2 2 0.2   NA   NA  1.344  324.0 
3 3 0.3   NA   NA  0.445  167.0 
4 4 0.4  1.455  354.2  0.322  321.2", header = TRUE) 

tcell <- read.table(text = " depth name 
1 0.2 Cell1 
2 0.4 Cell2 
3 0.6 Cell3 
4 0.8 Cell4", header = TRUE) 

然後解決你的問題:

library(reshape2) 

#Melt into long format 
df.m <- melt(df, id.vars = 1:2) 
#Split the column into two new columns based on _ 
df.m[, c("Cell", "OtherCol")] <- with(df.m, colsplit(variable, "_", c("Cell", "OtherCol"))) 
#Merge together with tcell 
df.m <- merge(df.m, tcell, by.x = "Cell", by.y = "name") 
#Add a new column which sets the offending values to NA 
df.m <- transform(df.m, newvalue = ifelse(value > depth.y, NA, value)) 
#Cast back into wide format 
dcast(pt + depth.x ~ variable, value.var = "newvalue", data = df.m) 

    pt depth.x Cell1_avgvel Cell1_avgdir Cell2_avgvel Cell2_avgdir 
1 1  0.1   NA   NA   NA   NA 
2 2  0.2   NA   NA   NA   NA 
3 3  0.3   NA   NA   NA   NA 
4 4  0.4   NA   NA  0.322   NA 
+0

在我看來,這個答案非常優雅,並且在向我展示reshape2可以使用的許多方法方面非常有幫助。 'value.var'對我來說是一個新技巧,將來會對我有所幫助。這種做法非常感謝! – svh160

+0

非常感謝您的幫助 – svh160

相關問題