R通过将变量分组

时间:2018-07-20 20:39:51

标签: r dplyr data.table

我有以下数据帧,每个用户具有多个任务分数:

sampDF<-structure(list(User = structure(c(1L, 1L, 2L, 2L, 2L), .Label = 
c("A1", 
"A2"), class = "factor"), Task.Name = structure(c(1L, 2L, 1L, 
3L, 4L), .Label = c("T1", "T2", "T3", "T4"), class = "factor"), 
Max.Score = c(0.93, 0.95, 0.78, 0.87, 0.96)), class = "data.frame", row.names = 
c(NA, 
-5L))

我想计算一个新变量(Score.Plus5),该变量仅在Max.Score且仅在第一个值{上添加常数(0.05)到<0.90值每个<0.90 {1}},否则我想要原始的User值。

我尝试使用Max.Score进行以下操作:

dplyr

这将导致每个ID重复sampDF2 <- sampDF %>% group_by(User) %>% arrange(User, Max.Score) %>% mutate(Score.Plus5 = ifelse(first(Max.Score <0.90), Max.Score + 0.05, Max.Score)) 值加上常量或原始Max.Score

我想要的结果是:

Max.Score

使用sampDF3<-structure(list(User = structure(c(1L, 1L, 2L, 2L, 2L), .Label = c("A1", "A2"), class = "factor"), Task.Name = structure(c(1L, 2L, 1L, 3L, 4L), .Label = c("T1", "T2", "T3", "T4"), class = "factor"), Max.Score = c(0.93, 0.95, 0.78, 0.87, 0.96), Score.Plus5 = c(0.93, 0.95, 0.83, 0.87, 0.96)), class = "data.frame", row.names = c(NA, -5L)) dplyr来获得此结果的最有效方法是什么?

3 个答案:

答案 0 :(得分:2)

在您的情况下,我认为first不是正确的选择,好像0,90的值小于true而不是该组所有行的row_number() == 1。因此,最好使用library(dplyr) sampDF %>% group_by(User) %>% arrange(User, Max.Score) %>% mutate(Score.Plus5 = ifelse(row_number()==1 & Max.Score <0.90, Max.Score + 0.05, Max.Score)) # # A tibble: 5 x 4 # # Groups: User [2] # User Task.Name Max.Score Score.Plus5 # <fctr> <fctr> <dbl> <dbl> # 1 A1 T1 0.930 0.930 # 2 A1 T2 0.950 0.950 # 3 A2 T1 0.780 0.830 # 4 A2 T3 0.870 0.870 # 5 A2 T4 0.960 0.960 。因此解决方案将是:

Import-Csv $file | where {$_.'Search Status' -ne "Blank line"} | select -skiplast 1 | Export-Csv "\file.csv" -notypeinfo

答案 1 :(得分:1)

这是一个data.table解决方案

library(data.table)
dt <- data.table(sampDF)
dt[, Score.Plus5 := 
     ifelse(1:.N == 1 & Max.Score < .9, Max.Score + .05, Max.Score), 
   by = User]
dt
#R    User Task.Name Max.Score Score.Plus5
#R 1:   A1        T1      0.93        0.93
#R 2:   A1        T2      0.95        0.95
#R 3:   A2        T1      0.78        0.83
#R 4:   A2        T3      0.87        0.87
#R 5:   A2        T4      0.96        0.96

代码假定数据从每个User开始排序。否则,假设setkeys可以按字母数字顺序排序(我收集的是您使用的顺序),请致电Task.Name

答案 2 :(得分:0)

  

仅在Max.Score的值和<0.90的第一个值<0.90的情况下,才向User值添加常数(0.05)

我会进行非股权加入...

library(data.table)
setDT(sampDF)

sampDF[, v := Max.Score]
sampDF[.(u = unique(User), s = 0.9), on=.(User == u, Max.Score <= s), mult="first", 
  v := v + 0.05][]

   User Task.Name Max.Score    v
1:   A1        T1      0.93 0.93
2:   A1        T2      0.95 0.95
3:   A2        T1      0.78 0.83
4:   A2        T3      0.87 0.87
5:   A2        T4      0.96 0.96

我正在发布,因为其他答案都可以解决

  

仅保留为每个<0.90的第一个值User

好像是

  

仅将User的第一个值设为<0.90

尽管通常它们并不相同。 (一种相同的特殊情况是,如果保证每个用户的最高得分得以提高。)