规范化具有多个条件的数据帧,R

规范化具有多个条件的数据帧,R,r,function,nan,na,normalize,R,Function,Nan,Na,Normalize,我有一个数据帧(df),它包含NA和数字。我希望在以下条件下对其进行规范化: 如果列只包含NA,则保持原样 如果一列只包含一个数字,而该列中的其余值等于NA,则将该值更改为1,将NA(该列中的所有NA)更改为0 如果列包含数字,则将其规格化 我做了以下尝试,但没有成功 normalize<-function(x) { x <- as.numeric( as.character( x )) if(sum(!is.na(x) == 1)) { x[which(!is.

我有一个数据帧(df),它包含
NA
和数字。我希望在以下条件下对其进行规范化:

  • 如果列只包含NA,则保持原样
  • 如果一列只包含一个数字,而该列中的其余值等于
    NA
    ,则将该值更改为
    1
    ,将
    NA
    (该列中的所有
    NA
    )更改为
    0
  • 如果列包含数字,则将其规格化
我做了以下尝试,但没有成功

normalize<-function(x) {
  x <- as.numeric( as.character( x ))
  if(sum(!is.na(x) == 1)) {
    x[which(!is.na(x))] <- 1
    x[which(is.na(x))] <- 0
    return(x)
  } else if(sum(!is.na(x) == 0)) {
    x <- NA
    return(x)
  } else if(sum(!is.na(x) > 1)) {
    y <- (x-min(x, na.rm=TRUE))/(max(x, na.rm=TRUE)-min(x, na.rm=TRUE))
    return(y)
  } 
}

as.data.frame(lapply(df, normalize))

normalize您的条件没有正常工作:
sum(!is.na(x)==1)
例如,这不是您想要的,因为您想要的是
sum
超过
!是.na(x)
,而不是
的总和!is.na(x)==1

以下内容将完成此工作:

df <- data.frame(a = c(123,534,7567,2345,3456,3476,NA,765), b = c(NA,NA,NA,NA,NA,NA,NA,NA), c = c(NA,NA,NA,NA,NA,354,NA,NA))

normalize<-function(x){
  if(sum(!is.na(x))==1){
    x[which(!is.na(x))] <- 1
    x[which(is.na(x))] <- 0
    return(x)
  }else if(sum(!is.na(x))==0){
    x <- NA
    return(x)
  }else if(sum(!is.na(x)>1)){
    y <- (x-min(x, na.rm=TRUE))/(max(x, na.rm=TRUE)-min(x, na.rm=TRUE)) 
    return(y)
  } 
}

as.data.frame(lapply(df, normalize))
              a  b c
[1,] 0.00000000 NA 0
[2,] 0.05519956 NA 0
[3,] 1.00000000 NA 0
[4,] 0.29848601 NA 0
[5,] 0.44773573 NA 0
[6,] 0.45042249 NA 1
[7,]         NA NA 0
[8,] 0.08623168 NA 0

df检查if上的括号。第一个标准将在除所有na以外的所有情况下返回真值,第二个标准似乎是偶然的。目前,y将是1,NA,或者是一个值向量
(x_i-min(x))/(范围(x)
,我不认为这是目的。请澄清您的条件。在您的问题中,我看到:(a)如果列都是NA,则保留它。(文本和代码);(b)如果它有一个非NA值,则将该值更改为1,并将所有NA更改为0(文本,代码中的错误);(c)如果列“包含数字”,则将其规范化(如果“包含数字”,则表示“所有其他情况”、文本和代码),但这是错误的,因为如果您的列具有单个值的多个副本,您将除以0。谢谢,但您的代码为数据帧的第一列生成1,这是错误的,您是-我的愚蠢错误。修复了上面的代码。规范化意味着将数据缩放到0到1的范围。查看结果后,我看到负数这不是我理解的标准化的意思。那么,上面给出的另一个解决方案有什么问题吗?亲爱的@iod,我想你忘了测试你的脚本。如果我比较从标准化形式得到的结果,这就是标准化
normalize<-function(x) {
    sapply(x, function(y) {if(all(is.na(y))) {y}
           else if(sum(!is.na(y))!=1) {helper<- (y-min(y, na.rm=TRUE))/(max(y, na.rm=TRUE)-min(y, na.rm=TRUE)) 
                                      helper}
           else if(sum(!is.na(y))==1) {helper<-ifelse(is.na(y),0,1)
                 helper}
    })
}
normalize(df)

              a  b c
[1,] 0.00000000 NA 0
[2,] 0.05519956 NA 0
[3,] 1.00000000 NA 0
[4,] 0.29848601 NA 0
[5,] 0.44773573 NA 0
[6,] 0.45042249 NA 1
[7,]         NA NA 0
[8,] 0.08623168 NA 0
df <- data.frame(a = c(123,534,7567,2345,3456,3476,NA,765), b = c(NA,NA,NA,NA,NA,NA,NA,NA), c = c(NA,NA,NA,NA,NA,354,NA,NA))

normalize<-function(x){
  if(sum(!is.na(x))==1){
    x[which(!is.na(x))] <- 1
    x[which(is.na(x))] <- 0
    return(x)
  }else if(sum(!is.na(x))==0){
    x <- NA
    return(x)
  }else if(sum(!is.na(x)>1)){
    y <- (x-min(x, na.rm=TRUE))/(max(x, na.rm=TRUE)-min(x, na.rm=TRUE)) 
    return(y)
  } 
}

as.data.frame(lapply(df, normalize))
              a  b c
[1,] 0.00000000 NA 0
[2,] 0.05519956 NA 0
[3,] 1.00000000 NA 0
[4,] 0.29848601 NA 0
[5,] 0.44773573 NA 0
[6,] 0.45042249 NA 1
[7,]         NA NA 0
[8,] 0.08623168 NA 0