【问题标题】:Relatively Referencing Observations in a function in RR中函数中的相对引用观察
【发布时间】:2017-07-21 14:22:02
【问题描述】:

在编写一个计算向量中每个观察值的函数时,我如何引用所述观察值以包含与当前正在操作的观察值相距预定数量的观察值的单元格?如果每一行都是i,使得i = 1、2、...等,我如何引用第i-1行的列?

这是一个模仿我的困境的示例数据集:

> letters <- c('a', 'b', 'c', 'b', 'e')
> numbers <- c('1', '', '2', '', '3')
> sample <- cbind(letters, numbers)
> sample
     letters numbers
[1,] "a"     "1"    
[2,] "b"     ""     
[3,] "c"     "2"    
[4,] "b"     ""     
[5,] "e"     "3"  

我想用之前观察到的sample$numbers 中的值填充sample$numbers 中的每个空单元格。我如何引用在其创建过程中创建的观察?例如,我尝试过:

> sample$numbers <- ifelse(sample$numbers == "", sample$numbers[as.numeric(rownames(sample)) - 1], sample$numbers)
Error in sample$numbers : $ operator is invalid for atomic vectors

我也尝试过在sample$letters 中使用常见的b 来填充缺失值:

> f1 <- function(df, cols, match_with, to_x = 'b'){
+   df[cols] <- lapply(df[cols], function(i) 
+     ifelse(grepl(to_x, match_with, fixed = TRUE), sample$numbers[as.numeric(rownames(sample)) - 1], 
+            i))
+   return(df)
+ }
> sample = f1(sample, cols = c('numbers'), match_with = sample$letters)
 Hide Traceback

 Rerun with Debug
 Error in sample$letters : $ operator is invalid for atomic vectors 
5.
grepl(to_x, match_with, fixed = TRUE) 
4.
ifelse(grepl(to_x, match_with, fixed = TRUE), sample$numbers[as.numeric(rownames(sample)) - 
    1], i) 
3.
FUN(X[[i]], ...) 
2.
lapply(df[cols], function(i) ifelse(grepl(to_x, match_with, fixed = TRUE), 
    sample$numbers[as.numeric(rownames(sample)) - 1], i)) 
1.
f1(sample, cols = c("numbers"), match_with = sample$letters) 

在这两种情况下,我的问题似乎是我在之前的观察中使用sample$numbers[as.numeric(rownames(sample)) - 1] 来引用sample$numbers 的值。有没有更好的方法来做到这一点?

【问题讨论】:

  • $ 仅适用于 listdata.frame,不适用于 matrix。您可以使用sample[, 2]sample[, "numbers"] 引用该列。我会尝试:sample[, 2] &lt;- ifelse(sample[, 2] == '', c('', head(sample[, 2], -1)), sample[, 2]).
  • 看看FillDown 包中的FillDown 函数。这是link

标签: r function if-statement missing-data rowname


【解决方案1】:
sample[,"numbers"] <- sapply(seq_along(sample[,"numbers"]), 
                             function(x) ifelse(sample[,"numbers"][x] == '', 
                                                sample[,"numbers"][x-1], 
                                                sample[,"numbers"][x]))

     letters numbers
[1,] "a"     "1"    
[2,] "b"     "1"    
[3,] "c"     "2"    
[4,] "b"     "2"    
[5,] "e"     "3"    

【讨论】:

    【解决方案2】:

    假设您有一个 data.frame 而不是上面使用的矩阵(为了能够使用$ 引用列),您可以为此使用zoo::na.locf

    #make a data.frame instead of a matrix
    sample <- data.frame(letters, numbers)
    
    library(zoo)
    #if your data has '' empty cells then convert those to NA
    sample$numbers[sample$numbers == ''] <- NA
    sample$numbers <- na.locf(sample$numbers)
    

    输出:

    sample
      letters numbers
    1       a       1
    2       b       1
    3       c       2
    4       b       2
    5       e       3
    

    【讨论】:

      【解决方案3】:

      您可以使用DataCombine 包中的FillDown 函数:

      library(DataCombine)
      letters <- c('a', 'b', 'c', 'b', 'e')
      numbers <- c('1', '', '2', '', '3')
      numbers[numbers==""] <- NA # replace empty strings with NA
      sample <- data.frame(letters,numbers)
      
      FillDown(sample,"numbers")
      

      【讨论】:

        【解决方案4】:
        letters <- c('a', 'b', 'c', 'b', 'e')
        numbers <- c('1', '', '2', '', '3')
        sample <- data.frame(letters, numbers, stringsAsFactors = F)
        
        
        sample$numbers[sample$numbers == ""] <- c(sample$numbers[2:nrow(sample)], NA)[sample$numbers == ""]
        

        【讨论】:

          猜你喜欢
          • 2017-10-09
          • 2021-07-12
          • 2019-06-15
          • 1970-01-01
          • 2017-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多