根据使用R

时间:2019-05-22 21:44:54

标签: r string if-statement

我想使用一个简单的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

有没有更好的方式组织上一次循环?

1 个答案:

答案 0 :(得分:1)

由于您似乎仍在使用小标题,因此使用 dplyr tidyr 的版本要短得多:

> 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
  • FUN中的apply参数需要一个函数,而不是一个任意表达式,这是您要在最后传递的内容。在这种情况下,“匿名”功能的一般语法为apply(...,FUN = function(arg) { do some stuff and return exactly the thing you want})