让我们制作一个虚拟数据集
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
我想创建一个新的数据帧,当ll的每列中的值小于a,b和&amp;的相应值时,它将变为0。 c在P的第一行;换句话说,我想看看
> 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
答案 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
,然后比较元素。
感谢Ananda Mahto认识到apply
不是必需的:
ll < c(P[1, names(ll)])
b c a
[1,] TRUE TRUE FALSE
[2,] TRUE TRUE FALSE
[3,] FALSE TRUE FALSE
TRUE
值显示您要用0替换的位置:
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
的多余调用。
答案 1 :(得分:0)
您也可以尝试mapply
,它将函数应用于每个相应的元素。在此,ll
和P
都是data.frames
。因此,它应用每列的功能并进行回收。在这里,我将column names
的{{1}}与P
的{{1}}匹配(类似于@Matthew Lundberg),并查找每列中ll
的哪些元素为ll
比相应的列(<
的一行被回收)并返回一个逻辑索引。然后将匹配逻辑条件的元素分配给P
。
0
答案 2 :(得分:0)
如果您知道ll
和P
是数字,那么您也可以将其作为
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