2012-06-06 39 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

相关问题