【问题标题】:Selectively replacing columns in R with their delta values有选择地用它们的增量值替换 R 中的列
【发布时间】:2010-12-03 06:30:24
【问题描述】:

我已按列将数据读入数据框 R。一些列的价值会增加;仅对于那些列,我想用与该列中前一个值的差异替换每个值 (n)。例如,查看单个列,我想要

c(1,2,5,7,8)

替换为

c(1,3,2,1)

哪些是连续元素之间的差异

但是,现在已经很晚了,我想我的大脑刚刚停止工作。这是我目前的代码

col1 <- c(1,2,3,4,NA,2,3,1) # This column rises and falls, so we want to ignore it
col2 <- c(1,2,3,5,NA,5,6,7) # Note: this column always rises in value, so we want to replace it with deltas
col3 <- c(5,4,6,7,NA,9,3,5) # This column rises and falls, so we want to ignore it
d <- cbind(col1, col2, col3)
d
fix_data <- function(data) {
    # Iterate through each column...
    for (column in data[,1:dim(data)[2]]) {
        lastvalue <- 0
        # Now walk through each value in the column, 
        # checking to see if the column consistently rises in value
        for (value in column) {
            if (is.na(value) == FALSE) { # Need to ignore NAs
                if (value >= lastvalue) {
                    alwaysIncrementing <- TRUE
                } else {
                    alwaysIncrementing <- FALSE
                    break
                }
            }
        }

        if (alwaysIncrementing) {
            print(paste("Column", column, "always increments"))
        }

        # If a column is always incrementing, alwaysIncrementing will now be TRUE
        # In this case, I want to replace each element in the column with the delta between successive
        # elements.  The size of the column shrinks by 1 in doing this, so just prepend a copy of
        # the 1st element to the start of the list to ensure the column length remains the same
        if (alwaysIncrementing) {
            print(paste("This is an incrementing column:", colnames(column)))
            column <- c(column[1], diff(column, lag=1))
        }
    }
    data
}

fix_data(d)
d

如果您将此代码复制/粘贴到 RGui 中,您会发现它对提供的数据框没有任何作用。

除了失去理智,我做错了什么??

提前致谢

【问题讨论】:

  • 你不会在任何地方分配 lastvalue...

标签: r diff


【解决方案1】:

没有详细说明代码,您将值分配给 column,它是循环内的局部变量(即在该上下文中 columndata 之间没有关系)。您需要将这些值分配给data 中的适当值。

另外,data 将是您的函数的本地地址,因此您需要在运行该函数后将其分配回 data

顺便说一句,您可以使用diff 查看是否有任何值在递增,而不是循环遍历每个值:

idx <- apply(d, 2, function(x) !any(diff(x[!is.na(x)]) < 0))
d[,idx] <- blah

【讨论】:

    【解决方案2】:

    diff 计算向量中连续值之间的差异。您可以将其应用于数据框中的每一列,例如

    dfr <- data.frame(x = c(1,2,5,7,8), y = (1:5)^2)
    as.data.frame(lapply(dfr, diff))
    
      x y
    1 1 3
    2 3 5
    3 2 7
    4 1 9
    

    编辑:我刚刚注意到了一些事情。您使用的是矩阵,而不是数据框(如您在问题中所述)。对于您的矩阵“d”,您可以使用

    d_diff <- apply(d, 2, diff)
    #Find columns that are (strictly) increasing
    incr <- apply(d_diff, 2, function(x) all(x > 0, na.rm=TRUE))
    #Replace values in the approriate columns
    d[2:nrow(d),incr] <- d_diff[,incr]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-15
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多