繁体   English   中英

R语言:用于处理数据框中的数据的功能

[英]R-language: function to process data in data frame

场景是存在一个函数,该函数从数据框中的列获取值,进行一些处理,然后用结果填充另一列。

这是测试的简化版本:

#the function checks if the value in inVar1 exists.
#if it does then it returns the value, if not it returns -100
#inRow: for debugging
test2 <- function (inVar1,inRow)
 {
  #debug
  print(paste("Row=",inRow, " inVar1=", inVar1, sep=''))

  if(is.na(inVar1) || is.null(inVar1))
   {
    #debug
    print("position 1")

    ret <- -100
   }
  else
   {
    #debug
    print("position 2")

    ret <- inVar1
   }

  #debug
  print("position 3")

  return(ret)
 }

简单功能测试:

> a <- test2(7,1)
[1] "Row=1 inVar1=7"
[1] "position 2"
[1] "position 3"
> print(a)
[1] 7
> 
> a <- test2(NA,1)
[1] "Row=1 inVar1=NA"
[1] "position 1"
[1] "position 3"
> print(a)
[1] -100

它按预期工作。

现在让我们创建一个数据框

> d1 <- data.frame(rowID=c(1,2,3), var1=c(2,NA,5))
> print(d1)
  rowID var1
1     1    2
2     2   NA
3     3    5

让我们测试从数据帧传递值的函数:

> a <- test2(d1[1,2],d1[1,1])
[1] "Row=1 inVar1=2"
[1] "position 2"
[1] "position 3"
> print(a)               
[1] 2
> a <- test2(d1[2,2],d1[2,1])
[1] "Row=2 inVar1=NA"
[1] "position 1"
[1] "position 3"
> print(a)               
[1] -100
> a <- test2(d1[3,2],d1[3,1])
[1] "Row=3 inVar1=5"
[1] "position 2"
[1] "position 3"
> print(a)
[1] 5

再次,它按预期工作。

现在,最后一件事。 我想用处理后的值添加一个新列。

d1$var2 <- test2(d1$var1,d1$rowID)
print(d1)

这将产生以下输出:

> d1$var2 <- test2(d1$var1,d1$rowID)
[1] "Row=1 inVar1=2"  "Row=2 inVar1=NA" "Row=3 inVar1=5" 
[1] "position 2"
[1] "position 3"
> print(d1)
  rowID var1 var2
1     1    2    2
2     2   NA   NA
3     3    5    5

第1行和第3行中var2的值按预期计算,但在第2行中为NA,而不是预期的-100。

我做错了什么?

我不明白的另一件事是,为什么我们只看到调试消息一次,却看不到行数,即三次?

谢谢!

您的函数未向量化。 您通过1对数字3次,每行一次,这是正确的,而最终测试一次通过1对向量。 每个变量1个向量。 为了使您的功能正常工作,您需要一次喂入一对。 mapply将为您做到这一点。

d1$var2 <- mapply(FUN = test2,inVar1 = d1$var1,inRow = d1$rowID)

但是总的来说,您可能需要考虑向量化来重写函数。

# "vectorised in the sense that it can operate on entire vectors at once"
test2vectbasic <- function(inVar1,inRow){
  # using mapply, but could be a basic for loop too
  mapply(FUN = test2,inVar1 = inVar1,inRow = inRow)
}

# efficient R vectorization that uses built in low level language loops
# using "existing R functions that are already vectorised"
test2vectbetter <- function(inVar1){
  ifelse(is.na(inVar1) | is.null(inVar1),-100,inVar1)
}

# sample data
d1 <- data.frame(rowID=c(1,2,3), var1=c(2,NA,5))

# mapply way
d1$var2 <- mapply(FUN = test2,inVar1 = d1$var1,inRow = d1$rowID)

# basic way on atoms or vectors
test2vectbasic(d1[2,2],d1[2,1])
d1$var3 <- test2vectbasic(d1$var1,d1$rowID)

# efficient way
test2vectbetter(d1[2,2],d1[2,1])
d1$var4 <- test2vectbetter(d1$var1)

要获得所需的功能,至少需要基本的向量化。 关于矢量化的一些资源:

如何对定义-一个矢量化功能,在-R

R inferno-转到地狱的第三圈-无法向量化

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM