R:如果单元格上下的值相互匹配,则更改单元格中的值,而不使用for循环
我正试图用数据帧上方或下方列中的值替换数据帧中的我们(或NAs,在我们中很容易被称为NAs)。即R:如果单元格上下的值相互匹配,则更改单元格中的值,而不使用for循环,r,loops,for-loop,apply,R,Loops,For Loop,Apply,我正试图用数据帧上方或下方列中的值替换数据帧中的我们(或NAs,在我们中很容易被称为NAs)。即 0 1 0 1 U U U U 0 1 1 0 将成为 0 1 0 1 0 1 U U 0 1 1 0 我有一个for循环来完成这项工作,它在数据的子集上工作 for(i in 2:((NROW(Sample_table))-1)) { for(j in 3:NCOL(Sample_table)) { if((Sample_table[i,j]=="U")&(Sample_t
0 1 0 1
U U U U
0 1 1 0
将成为
0 1 0 1
0 1 U U
0 1 1 0
我有一个for循环来完成这项工作,它在数据的子集上工作
for(i in 2:((NROW(Sample_table))-1)) {
for(j in 3:NCOL(Sample_table)) {
if((Sample_table[i,j]=="U")&(Sample_table[(i-1),j]==Sample_table[(i+1),j])){
Sample_table[i,j] <- Sample_table[(i+1),j]
}
}
}
我假设您只希望在第一行和第三行中的条目匹配时替换第二行中的条目 使用
replace
可能会出现类似的情况
# Sample data (as matrix)
mat <- as.matrix(read.table(text =
"0 1 0 1
U U U U
0 1 1 0", header = F))
apply(mat, 2, function(x) replace(x, x[1] == x[3] & x[2] == "U", x[1]))
# V1 V2 V3 V4
#[1,] "0" "1" "0" "1"
#[2,] "0" "1" "U" "U"
#[3,] "0" "1" "1" "0"
在
zoo
包中,有一个名为na.approx
的方法,它将在两个值之间进行插值。还有一个na.locf
,它接受前面的值。这两者结合在一起可以帮助你
- 用NAs替换U
- 存储所有NAs的位置
- 应用na.近似值
- 申请不适用
- 对于两个位置相同的位置,保留该值
- 所有其他人可能都需要回到U(或者在这种情况下你想做的任何事情)
这里可以找到一个相关的问题:正如Ral提到的,您可以将
zoo
与na.locf
mat1=mat
mat1[mat1=='U']=NA
mask=zoo::na.locf(mat1)==zoo::na.locf(mat1,fromLast=T)
mat[mask]=zoo::na.locf(mat1,fromLast=T)[mask]
mat
V1 V2 V3 V4
[1,] "0" "1" "0" "1"
[2,] "0" "1" "U" "U"
[3,] "0" "1" "1" "0"
这里是一个简单的解决方案,只使用base R和
apply
函数。此解决方案还假设“U”不在第一行或最后一行。此外,这还假设数据存储在数据帧中
df <- read.table(text =
"0 1 0 1 0 1 1 0
U U U U 1 0 1 1
0 1 1 0 0 1 0 1
0 1 0 1 0 1 1 0
U U U U 1 0 1 1
0 1 1 0 0 1 0 1", header = F)
df[]<-apply(df, 2, function(x){
#find rows with U
us<-which(x=="U" )
#replace U with value above (if above=below)
x[us]<-ifelse(x[us-1]==x[us+1], x[us-1], "U")
return(x)
})
df使用dplyrlead()
和lag()
myfunc是的,这看起来像我要做的!这是我无法理解的x[n]部分!我将检查并查看这是否在我的真实数据的子集中给出了预期结果。非常感谢。好的:所以这并不是我想要的:@DavidAshbrook现在只看到了你的评论(当时是澳大利亚的夜间;-)是的,我的解决方案没有立即扩展到更大的数据。frame
s,我认为原来的3行数据。frame
代表了你的一般问题。不管怎样,很高兴你从戴夫那里得到了一个有效的解决方案。很适合添加基准分析+1兴趣。随着示例表中行数的增加。我希望apply
方法中的向量化ifelse
语句的性能比原始for循环快100-1000倍。很高兴你有一个有效的解决方案。这是我使用的方法,速度最快,效果最好。我要添加的唯一注释是,有必要在开始和结束处添加一行0:以U开头的列,否则脚本将被中断。再次感谢你的帮助。
# Sample data (as matrix)
mat <- as.matrix(read.table(text =
"0 1 0 1
U U U U
0 1 1 0", header = F))
apply(mat, 2, function(x) replace(x, x[1] == x[3] & x[2] == "U", x[1]))
# V1 V2 V3 V4
#[1,] "0" "1" "0" "1"
#[2,] "0" "1" "U" "U"
#[3,] "0" "1" "1" "0"
# Sample data (as data.frame)
df <- read.table(text =
"0 1 0 1
U U U U
0 1 1 0", header = F)
as.data.frame(sapply(df, function(x) replace(x, x[1] == x[3] & x[2] == "U", x[1])))
# V1 V2 V3 V4
#1 0 1 0 1
#2 0 1 U U
#3 0 1 1 0
mat1=mat
mat1[mat1=='U']=NA
mask=zoo::na.locf(mat1)==zoo::na.locf(mat1,fromLast=T)
mat[mask]=zoo::na.locf(mat1,fromLast=T)[mask]
mat
V1 V2 V3 V4
[1,] "0" "1" "0" "1"
[2,] "0" "1" "U" "U"
[3,] "0" "1" "1" "0"
df <- read.table(text =
"0 1 0 1 0 1 1 0
U U U U 1 0 1 1
0 1 1 0 0 1 0 1
0 1 0 1 0 1 1 0
U U U U 1 0 1 1
0 1 1 0 0 1 0 1", header = F)
df[]<-apply(df, 2, function(x){
#find rows with U
us<-which(x=="U" )
#replace U with value above (if above=below)
x[us]<-ifelse(x[us-1]==x[us+1], x[us-1], "U")
return(x)
})
myfunc <- function(my_list) {
mlead <- lead(my_list, default = 'U')
mlag <- lag(my_list, default = 'U')
valuetocopy <- (my_list == 'U') & ((mlead == mlag))
my_list[valuetocopy] <- mlead[valuetocopy]
return(my_list)
}