R 基于单独的列值删除每行的列

R 基于单独的列值删除每行的列,r,R,给定如下所示的虚拟数据帧: Data1<-rnorm(20, mean=20) Data2<-rnorm(20, mean=21) Data3<-rnorm(20, mean=22) Data4<-rnorm(20, mean=19) Data5<-rnorm(20, mean=20) Data6<-rnorm(20, mean=23) Data7<-rnorm(20, mean=21) Data8<-rnorm(20, mean=25) Inde

给定如下所示的虚拟数据帧:

Data1<-rnorm(20, mean=20)
Data2<-rnorm(20, mean=21)
Data3<-rnorm(20, mean=22)
Data4<-rnorm(20, mean=19)
Data5<-rnorm(20, mean=20)
Data6<-rnorm(20, mean=23)
Data7<-rnorm(20, mean=21)
Data8<-rnorm(20, mean=25)
Index<-rnorm(20,mean=5)

DF<-data.frame(Data1,Data2,Data3,Data4,Data5,Data6,Data7,Data8,Index)

Data1如果您不介意将data.frame更改为矩阵,下面是一个使用矩阵索引的解决方案。构建两列要删除的索引矩阵是对
apply
函数系列的一次很好的回顾:

Seq      <- seq(Min, Max, by = 0.5)
col.idx  <- lapply(findInterval(DF$Index, Seq) + 1, seq, to = NumCol)
row.idx  <- mapply(rep, seq_along(col.idx), sapply(col.idx, length))
drop.idx <- as.matrix(data.frame(unlist(row.idx), unlist(col.idx)))

M <- as.matrix(DF)
M[drop.idx] <- NA

Seq这里是一个高效内存(但我不能说是优雅的)data.table解决方案

它使用非常有用的函数
findInterval
来更改小于/大于循环

# 
library(data.table)
DT <- data.table(DF)
# create an index column which 1:8 represent your greater than less than
DT[,IND := findInterval(Index, c(-Inf, seq(2,5,by =0.5 ), Inf))]

# the columns you want to change
changing <- names(DT)[1:8]


setkey(DT, IND)
# loop through the indexes and alter by reference
for(.ind in DT[,unique(IND)]){
   # the columns you want to change
   .which <- tail(changing, .ind)
   # create a call to `:=`(a = as(NA, class(a), b= as(NA, class(b))
   pairlist <- mapply(sprintf, .which, .which, MoreArgs = list(fmt =  '%s = as(NA,class(%s))'))
   char_exp <- sprintf('`:=`( %s )',paste(pairlist, collapse = ','))  
 .e <- parse(text = char_exp)
  DT[J(.ind), eval(.e)]

}
#
库(数据表)

DT是
as(NA,class..,
位以避免强制警告?如果是这样,可能更容易用
suppressWarnings
包装。或者,可能是
数据。当RHS只是
NA
时,表
无法警告强制(可能是一个不错的新功能)。然后可以删除
mappy
sprintf
,3行变为:
DT[J(.ind),更改:=NA,with=FALSE]
。否,由于NA是逻辑的,字符是数字的,因此停止错误(错误不是警告)。对不起,我不懂。哪个字符是数字?但没有字符列。它们都是数字或整数。为什么字符列会有任何不同?
Seq      <- seq(Min, Max, by = 0.5)
col.idx  <- lapply(findInterval(DF$Index, Seq) + 1, seq, to = NumCol)
row.idx  <- mapply(rep, seq_along(col.idx), sapply(col.idx, length))
drop.idx <- as.matrix(data.frame(unlist(row.idx), unlist(col.idx)))

M <- as.matrix(DF)
M[drop.idx] <- NA
# 
library(data.table)
DT <- data.table(DF)
# create an index column which 1:8 represent your greater than less than
DT[,IND := findInterval(Index, c(-Inf, seq(2,5,by =0.5 ), Inf))]

# the columns you want to change
changing <- names(DT)[1:8]


setkey(DT, IND)
# loop through the indexes and alter by reference
for(.ind in DT[,unique(IND)]){
   # the columns you want to change
   .which <- tail(changing, .ind)
   # create a call to `:=`(a = as(NA, class(a), b= as(NA, class(b))
   pairlist <- mapply(sprintf, .which, .which, MoreArgs = list(fmt =  '%s = as(NA,class(%s))'))
   char_exp <- sprintf('`:=`( %s )',paste(pairlist, collapse = ','))  
 .e <- parse(text = char_exp)
  DT[J(.ind), eval(.e)]

}