【问题标题】:R apply function to each row of dataframe, store result in new column of same dataframeR将函数应用于数据帧的每一行,将结果存储在同一数据帧的新列中
【发布时间】:2014-08-27 14:32:20
【问题描述】:

我想对数据框的每一行应用一个函数,并将结果存储在同一数据框中的一个新列中。该函数查看 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, : 找不到函数 ":="

【问题讨论】:

  • 你可能需要试试cut
  • @akrun 它们应该是数字的,但也许我的导入/之前的争吵有点捏造了。感谢您指出并提供一个好的答案。

标签: r function dataframe


【解决方案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

【讨论】:

  • 我认为 with 有点无意义 - 通过在 cut 函数中键入 so_example$Age.At.Event 来节省一些击键。
  • 太棒了,知道有一个更简单的解决方案。谢谢@akrun!
  • @Spacedman 谢谢。我养成了输入with 的习惯。改了。
  • “删除了正文中的 14 个字符”想想您现在可以与朋友和家人一起度过的所有额外时间
猜你喜欢
  • 2021-12-03
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多