2014-10-03 69 views
1

一个数据帧有条件的置换对象列值的让我们做一个虚拟数据集中,使用R

ll = data.frame(rbind(c(2,3,5), c(3,4,6), c(9,4,9))) 
colnames(ll)<-c("b", "c", "a") 
> ll 
    b c a 
1 2 3 5 
2 3 4 6 
3 9 4 9 

P = data.frame(cbind(c(3,5), c(4,6), c(8,7))) 
colnames(P)<-c("a", "b", "c") 
> P 
    a b c 
1 3 4 8 
2 5 6 7 

我想创建一个新的数据帧,其中L1中的每一列中的值会变成0时,它小于p的第一行中的a,b,& c的对应值;换句话说,我希望看到

> new_ll 
    b c a 
1 0 0 5 
2 0 0 6 
3 9 0 9 

所以我尝试了这种方式

nn=c("a", "b", "c") 
new_ll = sapply(nn, function(i) 
    ll[,paste0(i)][ll[,paste0(i)] < P[,paste0(i)][1]] <- 0) 

但它并不适用于某些原因!我必须在我的剧本中犯一个愚蠢的错误!任何想法?

> new_ll 
a b c 
0 0 0 

回答

1

您可以找到值ll是比P第一排小有apply

t(apply(ll, 1, function(x) x<P[1,][colnames(ll)])) 
     [,1] [,2] [,3] 
[1,] TRUE TRUE FALSE 
[2,] TRUE TRUE FALSE 
[3,] FALSE TRUE FALSE 

这里,P第一行是有序的匹配ll,那么元素进行比较。

感谢阿难Mahto,其识别apply不需要:您希望用0来代替

ll < c(P[1, names(ll)]) 
     b c  a 
[1,] TRUE TRUE FALSE 
[2,] TRUE TRUE FALSE 
[3,] FALSE TRUE FALSE 

TRUE值显示:

ll[ ll < c(P[1, names(ll)]) ] <- 0 
ll 
    b c a 
1 0 0 5 
2 0 0 6 
3 9 0 9 

要解决你的代码,你想要的东西像这样:

do.call(cbind, lapply(names(ll), function(i) { 
    ll[,i][ll[,i] < P[,i][1]] <- 0 
    return(ll[i])})) 
    b c a 
1 0 0 5 
2 0 0 6 
3 9 0 9 

发生了什么变化?首先,sapply更改为lapply,函数为每次迭代返回一个向量。其次,名称以预期结果的正确顺序呈现。第三,结果与cbind放在一起得到最终矩阵。作为奖励,对paste0的多余呼叫已被删除。

+0

感谢,但什么是错我的代码...我的意思是,为什么sapply不起作用? – ToNoY 2014-10-03 16:07:39

+1

你的代码不起作用,因为该函数没有返回任何有用的东西。 – 2014-10-03 16:11:08

+1

这里我不认为“应用”是必需的。你不能只是[ll A5C1D2H2I1M1N2O1R2T1 2014-10-03 16:34:06

0

您也可以尝试mapply,它将函数应用于每个对应的元素。这里,llP都是data.frames。因此,它适用于每个色谱柱的功能,并进行回收。在这里,我匹配Pcolumn namesll(与@Matthew Lundberg相似)的column names,并且查找每列中ll的哪些元素是<比对应列(P的一行被回收)并且返回逻辑索引。然后将符合逻辑条件的元素分配给0

indx <- mapply(`<`, ll, P[1,][names(ll)]) 
new_ll <- ll 
new_ll[indx] <- 0 
new_ll 
# b c a 
#1 0 0 5 
#2 0 0 6 
#3 9 0 9 
0

如果你知道llP都是数字,你可以做到这一点也为

llm <- as.matrix(ll) 
pv <- as.numeric(P[1, colnames(llm)]) 
llm[sweep(llm, 2, pv, `<=`)] <- 0 
data.frame(llm) 
# b c a 
# 1 0 0 5 
# 2 0 0 6 
# 3 9 0 9