R对每行数据帧应用函数,将结果存储在同一数据帧的新列中

时间:2014-08-27 14:32:21

标签: r function dataframe

我想将一个函数应用于datafame的每一行,并将结果存储在同一数据帧的新列中。该函数查看Age.At.Event的值并返回它所属的Age.Category。

以下是数据框:

dput(so_example)
structure(list(Age.At.Event = c(4L, 9L, 7L, 13L, 13L, 13L, 11L, 
11L, 14L, 4L, 15L, 14L, 3L, 12L, 12L, 8L, 13L, 11L, 11L, 11L), 
    Dosage = c(4.9, 0, 3.9, 2.54, 5.51, 24.75, 4.99, 36.59, 2.69, 
    0.83, 2.36, 45.01, 0.96, 1.53, 0.97, 1.2, 4.96, 38.99, 5.95, 
    0), Dosage.typ = structure(c(10L, 7L, 10L, 10L, 10L, 10L, 
    10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
    10L, 10L), .Label = c("", "CGYCM2", "DGYCM2", "DLP", "GYCM2", 
    "MGY", "MGYCM", "MGYCM2", "MGYM2", "UGYM2"), class = "factor"), 
    kVp = c(70, 0, 66, 0, 0, 70, 70, 80, 63, 70, 66, 0, 70, 85, 
    60, 90, 70, 80, 70, 70), mAs = c(2, 0, 1.2, 0, 0, 2, 1.1, 
    4.9, 1, 1.6, 0.9, 0, 2, 1.7, 0.9, 1.4, 2, 3.2, 1.5, 1.5)), .Names = c("Age.At.Event", 
"Dosage", "Dosage.typ", "kVp", "mAs"), row.names = c(1L, 2L, 
3L, 4L, 5L, 6L, 8L, 9L, 10L, 15L, 16L, 17L, 18L, 19L, 20L, 22L, 
23L, 24L, 25L, 26L), class = "data.frame")

so_example
   Age.At.Event Dosage Dosage.typ kVp mAs
1             4   4.90      UGYM2  70 2.0
2             9   0.00      MGYCM   0 0.0
3             7   3.90      UGYM2  66 1.2
4            13   2.54      UGYM2   0 0.0
5            13   5.51      UGYM2   0 0.0
6            13  24.75      UGYM2  70 2.0
8            11   4.99      UGYM2  70 1.1
9            11  36.59      UGYM2  80 4.9
10           14   2.69      UGYM2  63 1.0
15            4   0.83      UGYM2  70 1.6
16           15   2.36      UGYM2  66 0.9
17           14  45.01      UGYM2   0 0.0
18            3   0.96      UGYM2  70 2.0
19           12   1.53      UGYM2  85 1.7
20           12   0.97      UGYM2  60 0.9
22            8   1.20      UGYM2  90 1.4
23           13   4.96      UGYM2  70 2.0
24           11  38.99      UGYM2  80 3.2
25           11   5.95      UGYM2  70 1.5
26           11   0.00      UGYM2  70 1.5

我编写了一个函数,它接受一个输入(每行中特定列的值)并返回一个基于该值的类别(编码为字符串)。这是我的功能:

ageCategories <- function(x){
  if(x < 1) "0-1"
  else if(x >= 1 & x < 4) "1-3"
  else if(x >= 4 & x < 8)  "4-7"
  else if(x >= 8 & x < 12) "8-11"
  else if(x >= 12 & x < 16) "12-16"
}

我希望输出看起来像这样:

   Age.At.Event Dosage Dosage.typ kVp mAs Age.Category
1             4   4.90      UGYM2  70 2.0   4-7
2             9   0.00      MGYCM   0 0.0  8-11
3             7   3.90      UGYM2  66 1.2   4-7
4            13   2.54      UGYM2   0 0.0 12-16
5            13   5.51      UGYM2   0 0.0 12-16
6            13  24.75      UGYM2  70 2.0 12-16
8            11   4.99      UGYM2  70 1.1  8-11
9            11  36.59      UGYM2  80 4.9  8-11
10           14   2.69      UGYM2  63 1.0 12-16
15            4   0.83      UGYM2  70 1.6   4-7
16           15   2.36      UGYM2  66 0.9 12-16
17           14  45.01      UGYM2   0 0.0 12-16
18            3   0.96      UGYM2  70 2.0   1-3
19           12   1.53      UGYM2  85 1.7 12-16
20           12   0.97      UGYM2  60 0.9 12-16
22            8   1.20      UGYM2  90 1.4  8-11
23           13   4.96      UGYM2  70 2.0 12-16
24           11  38.99      UGYM2  80 3.2  8-11
25           11   5.95      UGYM2  70 1.5  8-11
26           11   0.00      UGYM2  70 1.5  8-11

该功能适用​​于单独的数字输入,但我似乎无法在数据帧中处理我的行。

我已经尝试在几个different ways中调用它,如下所示,但是我有点卡住了。我怀疑我的回答是在plyr包中,但是没有任何运气也没有运气。有人能否解释我做错了什么?

so_example$Age.Category <- apply(so_example, 1, ageCategories(.(Age.At.Event)))
  

ageCategories中的错误(。(Age.At.Event)):(列表)对象不能   被强制输入'double'

so_example[,Age.Category:=sapply(Age.At.Event,ageCategories)][]
  

[.data.frame中的错误(so_example ,, :=(Age.Category,   sapply(Age.At.Event,:找不到函数“:=”

1 个答案:

答案 0 :(得分:1)

so_example$Age.Category <- cut(so_example$Age.At.Event, 
         breaks=c(-Inf, 1,3,7,11,16), labels=c('0-1', '1-3', '4-7', '8-11','12-16')) 

 so_example
#   Age.At.Event Dosage Dosage.typ kVp mAs Age.Category
#1             4   4.90      UGYM2  70 2.0          4-7
#2             9   0.00      MGYCM   0 0.0         8-11
#3             7   3.90      UGYM2  66 1.2          4-7
#4            13   2.54      UGYM2   0 0.0        12-16
#5            13   5.51      UGYM2   0 0.0        12-16
#6            13  24.75      UGYM2  70 2.0        12-16
#8            11   4.99      UGYM2  70 1.1         8-11
#9            11  36.59      UGYM2  80 4.9         8-11
#10           14   2.69      UGYM2  63 1.0        12-16
#15            4   0.83      UGYM2  70 1.6          4-7
#16           15   2.36      UGYM2  66 0.9        12-16
#17           14  45.01      UGYM2   0 0.0        12-16
#18            3   0.96      UGYM2  70 2.0          1-3
#19           12   1.53      UGYM2  85 1.7        12-16
#20           12   0.97      UGYM2  60 0.9        12-16
#22            8   1.20      UGYM2  90 1.4         8-11
#23           13   4.96      UGYM2  70 2.0        12-16
#24           11  38.99      UGYM2  80 3.2         8-11
#25           11   5.95      UGYM2  70 1.5         8-11
#26           11   0.00      UGYM2  70 1.5         8-11