【问题标题】:Applying R function over multiple columns and generating output在多列上应用 R 函数并生成输出
【发布时间】:2020-10-03 08:19:13
【问题描述】:

我正在尝试生成一个基于另一个数据框的值的新数据框。

我的旧数据框具有每个变量和观察值的平均值,如下所示:

    var1   var2   var3
#1: 2.1    3.4    2.7
#2  1.1    3.6    2.2
#3  2.9    1.7    2.7
data <- structure(list(var1 = c(2.1, 1.1, 2.9), var2 = c(3.4, 3.6, 1.7
), var3 = c(2.7, 2.2, 2.7)), class = "data.frame", row.names = c(NA, -3L))

我的目标是创建一个数据框,该数据框应包含原始数据框中每个观察值的 10 个观察值。这些观察结果应该复制平均值。它应该是这样的

   var 1 var 2  var 3
#1  2     3      2
#1  2     3      2
#1  2     3      2
#1  2     3      3
#1  2     3      3
#1  2     3      3 
#1  2     4      3
#1  2     4      3
#1  2     4      3
#1  3     4      3

现在要创建这些观察结果,我正在使用这个函数:

my_func <- function(y){
  wert <- y
  werte <- wert
  werte2 <- floor(werte)
  werte3 <- floor(werte)+1
  werte4 <- round((werte-werte2)*10)
    werte5 <- round(10-(werte-floor(werte))*10)
    y <- as.vector(rep(werte2,werte5))
  z <- as.vector(rep(werte3,werte4))
  b <- c(y,z)
  b
  }

之后,我将此函数应用于数据并将其存储到列表中:

myList<- list()
for (i in 1:ncol){
pp <- lapply(data[,i],my_func)
myList[[i]] <- pp
}

很遗憾,执行此操作时出错:

rep(werte2, werte5) 中的错误:'times' 参数无效
调用自:as.vector(rep(werte2, werte5))

有没有办法解决这个问题或更好的方法?

【问题讨论】:

  • 你想要的“10个观察”有什么具体要求吗?例如,如果您需要一组 10 个平均值为 3.4 的数字,为什么不直接使用 rep(3.4, 10)?你要求它们是自然数吗?这 10 个数字中的任何一个是 floor(3.4) 还是 ceiling(3.4)?
  • 是的,数字需要整数。它们的范围在 0 到 5 之间。

标签: r output apply


【解决方案1】:

试试这个:

my_func <- function(x) {
  int_x <- as.integer(floor(x))
  dec_x <- as.integer(x * 10 - int_x * 10)
  out <- vapply(
    seq_along(x), 
    function(i, a, b) rep(a[[i]], 10L) + c(rep(0L, 10L - b[[i]]), rep(1L, b[[i]])), 
    integer(10L), int_x, dec_x
  )
  `attributes<-`(out, NULL)
}
as.data.frame(lapply(df, my_func))

输出

> as.data.frame(lapply(df, my_func))
   var1 var2 var3
1     2    3    2
2     2    3    2
3     2    3    2
4     2    3    3
5     2    3    3
6     2    3    3
7     2    4    3
8     2    4    3
9     2    4    3
10    3    4    3
11    1    3    2
12    1    3    2
13    1    3    2
14    1    3    2
15    1    4    2
16    1    4    2
17    1    4    2
18    1    4    2
19    1    4    3
20    2    4    3
21    2    1    2
22    3    1    2
23    3    1    2
24    3    2    3
25    3    2    3
26    3    2    3
27    3    2    3
28    3    2    3
29    3    2    3
30    3    2    3

【讨论】:

    【解决方案2】:

    我认为您需要这样的功能:

    unmean <- function(vec, n = 10) {
      as.numeric(sapply(vec,  function(x) {
        c(rep(floor(x), round(n * (1 - x %% 1))), 
          rep(ceiling(x), round(n * (x %% 1))))
      }))
    }
    

    这允许你做例如:

    unmean(2.5, n = 2)
    #> [1] 2 3
    
    unmean(3.2, n = 5)
    #> [1] 3 3 3 3 4
    
    unmean(c(2.1, 6.7), 10)
    #> [1] 2 2 2 2 2 2 2 2 2 3 6 6 6 7 7 7 7 7 7 7
    

    因此,对于您的解决方案,您会这样做:

    as.data.frame(lapply(data, unmean))
    #>    var1 var2 var3
    #> 1     2    3    2
    #> 2     2    3    2
    #> 3     2    3    2
    #> 4     2    3    3
    #> 5     2    3    3
    #> 6     2    3    3
    #> 7     2    4    3
    #> 8     2    4    3
    #> 9     2    4    3
    #> 10    3    4    3
    #> 11    1    3    2
    #> 12    1    3    2
    #> 13    1    3    2
    #> 14    1    3    2
    #> 15    1    4    2
    #> 16    1    4    2
    #> 17    1    4    2
    #> 18    1    4    2
    #> 19    1    4    3
    #> 20    2    4    3
    #> 21    2    1    2
    #> 22    3    1    2
    #> 23    3    1    2
    #> 24    3    2    3
    #> 25    3    2    3
    #> 26    3    2    3
    #> 27    3    2    3
    #> 28    3    2    3
    #> 29    3    2    3
    #> 30    3    2    3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-06
      • 2022-01-06
      • 2015-04-17
      • 1970-01-01
      • 2019-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多