我在R中有一个数据框架,其中包含倍数变化(fc)的测量值和fc_0.1,fc_0.2等列。直到fc_2。我尝试在每列的每一行中填充1,如果它等于或大于基于特定列名的第一列的值。我最初通过指定每一列来完成这项工作,这非常繁琐,现在我正试图缩短代码并将其通用化。我做了这个for循环做了很多工作,但是我无法将这些if语句集成到循环中。如果我不需要为每一个0.1的增量写一个if语句,那就太好了。
fc <- c(0.82,0.03,1.52,0.14,0.61,1.88,0.29,1.91,0.32,0.46,1.76,0.54,1.45,2.01,0.71,1.45,0.90,1.01,1.17,1.68,1.21,1.37)
data<- data.frame(abs(fc)) # create a data frame fold change
z<- data.frame(rep.int(0, 22))
z[2:20] <- z[[1]] # create a data frame of zeros
data <- data.frame(data,z) # add the two data frames together
names(data) <- c("fc",paste0("fc_", seq(0.1, 2, by = 0.1))) # give names to the columns
data
for(i in 1:nrow(data)){
for(j in 2:ncol(data)){
if(data[i,1]>=0.1){
data[i,2]=1
}
if(data[i,1]>=0.2){
data[i,3]=1
}
if(data[i,1]>=0.3){
data[i,4]=1
}
if(data[i,1]>=0.4){
data[i,5]=1
}
if(data[i,1]>=0.5){
data[i,6]=1
}
if(data[i,1]>=0.6){
data[i,7]=1
}
if(data[i,1]>=0.7){
data[i,8]=1
}
if(data[i,1]>=0.8){
data[i,9]=1
}
if(data[i,1]>=0.9){
data[i,10]=1
}
if(data[i,1]>=1.0){
data[i,11]=1
}
}
}
data
如果我想填充所有的列,我必须为所有的0.1增量编写一个if语句。这使得代码非常长,如果我增加所需的值的数量,代码将不可伸缩。
我尝试了第三个for循环,尝试对每一列的if语句计算的数字进行积分。
for(i in 1:nrow(data)){
for(j in 2:ncol(data)){
for(k in seq(0.1, 2, by = 0.1)){
if(data[i,1]>=k){
data[i,j]=1
}
}
}
}
这会在每一行和每一列中填充1,而不管第一列的值是多少(除了0.03,它仍然神秘地填充0)。我无法找到一种方法来使我的代码更容易,但我知道它可以以某种方式完成。请帮帮忙。
2条答案
按热度按时间oxcyiej71#
看起来很晦涩,这是更惯用的R:
浏览:
as.numeric(sub(..))
只是提取和编号化列名,结果为c(0.1, 0.2, 0.3, 0.4, ..., 2)
。data[[1]]
可以是data$fc
或其他值,它只返回您需要的实际fc
数字outer(val1, val2,
<)
使用val2
中的所有值对val1
中的所有值进行外部计算。它返回一个维度为length(val1)
xlength(val2)
的矩阵:1
s和0
s,所以我们将其 Package 在+(..)
中,以实现R从逻辑到整数隐式转换:data[,-1] <- ...
。一些想法:在R中,通常将事物作为整体向量而不是元素来处理要快得多。比如说,
做十个比较,但表达(至少在我的脑海中)要简单得多,容易理解。这种逻辑可以扩展到矩阵等(尽管我在这里没有使用)。我们在对
outer
的调用中隐式地使用了<
操作。在内部,outer
产生两个更长的向量。对于一个小得多的例子,请注意,它将
vec1
扩展为length(vec1)*length(vec2)
的长度,其中vec1
作为一个整体重复length(vec2)
次;并且它对每个值重复vec2
×length(vec1)
次,更缓慢地改变值。有了这个,
a
(我们的anon函数的第一个参数)和b
都是相同的长度,那么它就只是a + b
,这是两个向量的分段相加。然后通过
outer
重新调整此输出的尺寸,以便它处于outer
所期望的正确矩阵中。(有时这个矩阵是不必要的,但是用c(outer(..))
将它反矩阵化是很简单的,然后它将重新标注为原始args的长度。数据
j2qf4p5b2#
这里有一个简短的,(我认为)可读的使用
across
的dplyr方法。这意味着我们要1)取data
,然后2)将除fc
之外的所有列更改为测试的数字版本(例如1表示TRUE,0表示FALSE),将当前列名的解析值与fc
中的值进行比较。结果
这是一个使用整形的tidyverse方法。对行编号,将长度调整为更长,将
fc
值与列名中的数字进行比较,然后再次调整宽度: