首页 > 解决方案 > 根据使用 R 满足的条件应用标签

问题描述

我想使用一个简单的 R 函数,其中指定数据框列的内容被逐行读取,然后根据值,将字符串应用于新列中的该行。

到目前为止,我尝试使用循环组合并生成稍后组合的单个列。但是,我似乎无法正确使用语法。

输入如下所示:

head(data,10)
# A tibble: 10 x 5
   Patient T1Score T2Score T3Score T4Score
     <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
 1       3    96.4    75      80.4    82.1
 2       5   100      85.7    53.6    55.4
 3       6    82.1    85.7    NA      NA  
 4       7    82.1    85.7    60.7    28.6
 5       8   100      76.8    64.3    57.7
 6      10    46.4    57.1    NA      75  
 7      11    71.4    NA      NA      NA  
 8      12    98.2    92.9    85.7    82.1
 9      13    78.6    89.3    37.5    42.9
10      14    89.3   100      64.3    87.5

我写的函数是这样的:

minMax<-function(x){

  #make an empty data frame for the output to go
  output<-data.frame()

    #making sure the rest of the commands only look at what I want them to look at in the input object
  a<-x[2:5]
  #here I'm gathering the columns necessary to perform the calculation
  minValue<-apply(a,1,min,na.rm=T)
  maxValue<-apply(a,1,max,na.rm=T)

  tempdf<-as.data.frame((cbind(minValue,maxValue)))

  Difference<-tempdf$maxValue-tempdf$minValue
  referenceValue<-ave(Difference)
  referenceValue<-referenceValue[1]

  #quick aside to make the first two thirds of the output file
  output<-as.data.frame((cbind(x[1],Difference)))

    #Now I need to define the class based on the referenceValue, and here is where I run into trouble.
  apply(output, 1, FUN = 
  for (i in Difference) {
  ifelse(i>referenceValue,"HIGH","LOW")

  }
  )
  output
  } 

我也试过...

    if (i>referenceValue) {
    apply(output,1,print("HIGH"))
   }else(print("LOW")) {}
  }
  )
  output
  } 


无论如何,两者最终都会给我错误信息,

 c("'for (i in Difference) {' is not a function, character or symbol", "'    ifelse(i > referenceValue, \"HIGH\", \"LOW\")' is not a function, character or symbol", "'}' is not a function, character or symbol") 

预期的输出应如下所示:

Patient Difference Toxicity
3  21.430000 LOW
5  46.430000 HIGH
6   3.570000 LOW
7  57.140000 HIGH
8  42.310000 HIGH
10  28.570000 HIGH
11   0.000000 LOW
12  16.070000 LOW
13  51.790000 HIGH
14  35.710000 HIGH

我有更好的方法来组织最后一个循环吗?

标签: rstringif-statement

解决方案


由于您似乎无论如何都在使用 tibbles,因此这里有一个使用dplyrtidyr的更短的版本:

> d %>%
  gather(key = tscore,value = score,T1Score:T4Score) %>%
  group_by(Patient) %>%
  summarise(Difference = max(score,na.rm = TRUE) - min(score,na.rm = TRUE)) %>%
  ungroup() %>%
  mutate(AvgDifference = mean(Difference),
         Toxicity = if_else(Difference > mean(Difference),"HIGH","LOW"))

# A tibble: 10 x 4
   Patient Difference AvgDifference Toxicity
     <int>      <dbl>         <dbl> <chr>   
 1       3       21.4          30.3 LOW     
 2       5       46.4          30.3 HIGH    
 3       6        3.6          30.3 LOW     
 4       7       57.1          30.3 HIGH    
 5       8       42.3          30.3 HIGH    
 6      10       28.6          30.3 LOW     
 7      11        0            30.3 LOW     
 8      12       16.1          30.3 LOW     
 9      13       51.8          30.3 HIGH    
10      14       35.7          30.3 HIGH    

我认为也许您的预期输出可能基于略有不同的平均差异,因此该输出略有不同。

如果您愿意,还有一个更简单的基本 R 版本:

d$min <- apply(d[,2:5],1,min,na.rm = TRUE)
d$max <- apply(d[,2:5],1,max,na.rm = TRUE)
d$diff <- d$max - d$min
d$avg_diff <- mean(d$diff)
d$toxicity <- with(d,ifelse(diff > avg_diff,"HIGH","LOW"))

关于现有代码的几点说明:

  • as.data.frame((cbind(minValue,maxValue)))不是创建数据框的可取方式。这比简单地做更尴尬,data.frame(minValue = minValue,maxValue = maxValue)并且冒着来自cbind.
  • ave用于计算组的摘要;仅mean在您有单个向量时使用
  • in的FUN参数apply需要一个函数,而不是任意表达式,这是您最后要传递的。在这种情况下,“匿名”函数的一般语法是apply(...,FUN = function(arg) { do some stuff and return exactly the thing you want}).

推荐阅读