【问题标题】:Replacing all negative values from a dataset替换数据集中的所有负值
【发布时间】:2018-06-13 15:52:36
【问题描述】:

我有一个dataframe,其中包含混合数据,从具有数值的变量(或列)到具有因子的变量(或列)。

我想在 R 中使用以下代码将所有负值替换为 NA,如果该变量的 99% 以上的观察结果为 NA,则随后删除整个变量。

第一部分应该确保遇到字符串时没有问题。 是否可以简单地开始:

mydata$v1[mydata$v1<0] <- NA 

但不是特定于v1 并且仅当观察不是字符串时?

跟进: 这就是我对@stas g 提供的解释的了解。然而,似乎没有从 df 中删除任何变量。

#mixed data
df <- data.frame(WVS_Longitudinal_1981_2014_R_v2015_04_18)
dat <- df[,sapply(df, function(x) {class(x)== "numeric" | class(x) == 
"integer"})]

foo <- function(dat, p){ 
  ind <- colSums(is.na(dat))/nrow(dat)
  dat[dat < 0] <- NA
  dat[, ind < p]
}

#process numeric part of the data separately
ii <- sapply(df, class) == "numeric" | sapply(df, class) == "integer"
dat.num <- foo(as.matrix(df[, ii]), 0.99)
#then stick the two parts back together again
WVS <- data.frame(df[, !ii], dat.num)

【问题讨论】:

  • 你需要提供一个最小可重现的例子

标签: r replace stata missing-data


【解决方案1】:

如果没有最小的可重复示例,就不可能确切知道如何为您提供帮助,但假设您有以下示例数据:

#matrix of random normal observations, 20 samples, 5 variables
dat <- matrix(rnorm(100), nrow = 20)
#if entry is negative, replace with 'NA'
dat[dat < 0] <- NA

#threshold for dropping a variable
p <- 0.99
#check how many NAs in each column (proportionally)
ind <- colSums(is.na(dat))/nrow(dat)
#only keep columns where threshold is not exceded
dat <- dat[, ind < p]

如果你有非数字变量并且你正在处理 data.frame 你可以做这样的事情(假设你不关心列的顺序):

#generate mixed data
dat <- matrix(rnorm(100), nrow = 20) #20 * 50 numeric numbers
df <- data.frame(letters[1 : 20], dat) #combined with one character column 


foo <- function(dat, p){ 
  ind <- colSums(is.na(dat))/nrow(dat)
  dat[dat < 0] <- NA
  dat[, ind < p]
}

#process numeric part of the data separately
ii <- sapply(df, class) == "numeric" #ind of numeric columns
dat.num <- foo(as.matrix(df[, ii]), 0.99) #feed numeric part of data to foo
#then stick the two partw back together again
data.frame(df[, !ii], dat.num)

【讨论】:

  • 感谢您的回答,尽管我的问题存在问题。我现在正在努力改进它。 R(studio) 不介意某些变量是字符串等吗?
  • 取决于你的意思。如果您的某些变量不是数字,您的数据将存储在 data.frame 而不是我的答案中的矩阵
  • 感谢您的帮助!我会在早上再过一遍。
  • 抱歉,我已经有一段时间没有时间研究这个问题了。我正在尝试将您的代码应用于我的数据。我假设如果我有一个数据集,我不会生成数据,但我将 dat 替换为我的数据集的名称(代码中的任何地方)。我仍然感到困惑的是df &lt;- data.frame(letters[1 : 20], dat) 的目的。你能解释一下吗?
  • @TomKisters 这只是创建了一个非数字列(充满从第 1 到第 20 个字母),以创建一个不仅仅是数字数据的 data.frame 示例
【解决方案2】:

@YOLO 建议的这种方法:Solution by YOLO 终于解决了这个问题:

cleanFun <- function(df){

    # set negative values as NA
    df[df < 0] <- NA

    # faster, vectorized solution
    # select numeric columns
    num_cols <- names(df)[sapply(df, is.numeric)]

    # get name of columns with 99% or more NA values
    col_to_remove <- names(df)[colMeans(is.na(df[num_cols]))>=0.99]

    # drop those columns
    return (df[setdiff(colnames(df),col_to_remove)])
}

your_df <- cleanFun(your_df)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 2019-06-08
    • 2022-01-24
    相关资源
    最近更新 更多