首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试图使用R中的函数在数据帧中创建新列

试图使用R中的函数在数据帧中创建新列
EN

Stack Overflow用户
提问于 2020-07-18 14:56:41
回答 2查看 65关注 0票数 2

我有一个大的数据框架,我想为R中的数据框架创建一个新的列,但我正在挣扎。我是一个相对初学者,我将非常感谢一些帮助。

本质上,我希望根据个人的峰值和基线肌酐测量,以及他们是否进行过肾脏替代治疗(RRT),根据以下标准创建AKI分期的新专栏:

第1阶段:峰值Cr /基线Cr =1.5-1.9或峰值Cr≥基线Cr+ 26.5mmol/l)

第二阶段:峰值Cr /基线Cr=2.02.9

第三阶段:峰值Cr /基线cr≥3或峰值cr≥353.6mmol/l或启动RRT

我的数据如下所示,其中有三个主要变量。

代码语言:javascript
复制
head(data)
 Peak.Creatinine.1 baseline.Cr.within.12.months new.RRT
1               421                           82       1
2               659                           98       1
3               569                           89       1
4               533                          113       1
5               533                          212       1
6               396                           65       1

我想创建一个名为"AKI.stage“的新列,它返回一个数字0、1、2、3或4。

代码语言:javascript
复制
akistage <- function(peak_cr, bl_cr, rrt=0) {
  ratio <- peak_cr / bl_cr
  if (rrt == "1"){return(3)}
  else if (ratio >= 3){return(3)}
  else if (peak_cr > 353.6){return(3)}
  else if (ratio > 2 & ratio <3){return(2)}
  else if (ratio > 1.5 & ratio <2){return(1)}
  else if ((peak_cr >= bl_cr + 26.5)){return(1)}
  else {return (0)}
}

当我测试它时,这个函数工作得很好,但是我似乎不能将它应用到dataframe来创建新的列。我尝试过多种方法,包括应用、应用、变异、转换等,但我似乎无法让它发挥作用。

以下是我的一些失败尝试:

代码语言:javascript
复制
data2$Peak.Creatinine.1 <- as.numeric(data2$Peak.Creatinine.1)
data2$baseline.Cr.within.12.months <- as.numeric(data2$baseline.Cr.within.12.months)
data2$test <- apply(data2, 1, function(x){
  ratio <- x[1] / x[2]
  peak_cr <- x[1]
  bl_cr <- x[2]
  rrt <- x[3]
  if (rrt == "1"){return(3)}
  else if (ratio >= 3){return(3)}
  else if (peak_cr > 353.6){return(3)}
  else if (ratio > 2 & ratio <3){return(2)}
  else if (ratio > 1.5 & ratio <2){return(1)}
  else if ((peak_cr >= bl_cr + 26.5)){return(1)}
  else {return (0)}
})

但这将返回以下错误消息,尽管是类数值的错误消息:

代码语言:javascript
复制
Error in x[1]/x[2] : non-numeric argument to binary operator

另一次尝试:

代码语言:javascript
复制
data2 %>% 
  mutate(test = 
           akistage(Peak.Creatinine.1,baseline.Cr.within.12.months,new.RRT))

返回

代码语言:javascript
复制
Warning message:
In if (rrt == "1") { :
  the condition has length > 1 and only the first element will be used

我尝试过很多其他的方法,但我不知道为什么它不起作用。这似乎不是很难做,我会非常感激,如果有人能想出一个解决办法!

非常感谢你的帮助!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-18 15:29:33

下面的向量化函数执行问题所描述的操作。它使用索引向量将返回值赋给先前创建的向量AKI.stage

代码语言:javascript
复制
akistage <- function(peak_cr, bl_cr, rrt = 0) {
  AKI.stage <- numeric(length(peak_cr))
  ratio <- peak_cr / bl_cr
  rrt1 <- rrt == 1
  i <- findInterval(ratio, c(0, 1.5, 2, 3, Inf))
  AKI.stage[rrt1 | i == 4 | peak_cr > 353.6] <- 3
  AKI.stage[!rrt1 & i == 3] <- 2
  AKI.stage[!rrt1 & i == 2] <- 1
  AKI.stage[!rrt1 & i == 1 & peak_cr >= bl_cr + 26.5] <- 1
  AKI.stage
}


data %>% 
  mutate(test = akistage(Peak.Creatinine.1,baseline.Cr.within.12.months,new.RRT))
票数 2
EN

Stack Overflow用户

发布于 2020-07-18 15:07:56

我建议您使用不同的解决方案将一个新的colum添加到data.frame中,只使用基R:

代码语言:javascript
复制
df <- data.frame(v1 = rep(0, 100), v2 = seq(1, 100))
v3 <- rep(0, 100)

# first way with a $
df$v3 <- v3

# second way with cbind
df <- cbind(df, v3)

# third way
df[, 3] <- 3

编辑1

您的问题来自于这样一个事实:您的第三列是factor,所以当您使用apply时,它会将所有数据转换为字符。做你想做的事的正确方法是:

代码语言:javascript
复制
sapply(1:nrow(data2), function(i, df){
  x <- df[i,]
  ratio <- x[1] / x[2]
  peak_cr <- x[1]
  bl_cr <- x[2]
  rrt <- x[3]
  if (rrt == "1"){return(3)}
  else if (ratio >= 3){return(3)}
  else if (peak_cr > 353.6){return(3)}
  else if (ratio > 2 & ratio <3){return(2)}
  else if (ratio > 1.5 & ratio <2){return(1)}
  else if ((peak_cr >= bl_cr + 26.5)){return(1)}
  else {return (0)}
}, df = data2)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62969995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档