【问题标题】:How can I apply cut() separately to each line of a data frame using purrr::map()?如何使用 purrr::map() 将 cut() 分别应用于数据帧的每一行?
【发布时间】:2020-03-08 09:29:50
【问题描述】:

我想对数据框应用特定的逐行操作。

我们的目标是创建一个新的数据框 - 或者我稍后将转换为数据框的列表 - 使用标签而不是数字。为了得到我想要的,我使用purrr::map() 将函数cut() 应用于编号数据框。

期望一个包含两个对象的列表,每个对象包含 15 个元素。 我得到的是一个包含 15 个对象的列表,每个对象包含 2 个元素。似乎 map 是按列应用的,而不是按行应用的。

下面的代码演示了正在发生的事情。

如何强制操作按行工作?

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(purrr)

a_matrix = matrix(data = sample(100,30),nrow = 2)
a_matrix
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
#> [1,]   72   29   47    9   44   62   73   60   56    85    21    78   100
#> [2,]   16   74   90   34   99   50    7   53   28    38    12    96    40
#>      [,14] [,15]
#> [1,]    51    22
#> [2,]    58    52

a_df = data.frame(a_matrix)
a_df
#>   X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15
#> 1 72 29 47  9 44 62 73 60 56  85  21  78 100  51  22
#> 2 16 74 90 34 99 50  7 53 28  38  12  96  40  58  52

cut_modif = function(x) {
  cut(x,
      breaks = quantile(x),
      labels = c("A", "B", "C", "D"),
      include.lowest = T,
      right = T
  )
}

map(a_df,cut_modif)
#> $X1
#> [1] D A
#> Levels: A B C D
#> 
#> $X2
#> [1] A D
#> Levels: A B C D
#> 
#> $X3
#> [1] A D
#> Levels: A B C D
#> 
#> $X4
#> [1] A D
#> Levels: A B C D
#> 
#> $X5
#> [1] A D
#> Levels: A B C D
#> 
#> $X6
#> [1] D A
#> Levels: A B C D
#> 
#> $X7
#> [1] D A
#> Levels: A B C D
#> 
#> $X8
#> [1] D A
#> Levels: A B C D
#> 
#> $X9
#> [1] D A
#> Levels: A B C D
#> 
#> $X10
#> [1] D A
#> Levels: A B C D
#> 
#> $X11
#> [1] D A
#> Levels: A B C D
#> 
#> $X12
#> [1] A D
#> Levels: A B C D
#> 
#> $X13
#> [1] D A
#> Levels: A B C D
#> 
#> $X14
#> [1] A D
#> Levels: A B C D
#> 
#> $X15
#> [1] A D
#> Levels: A B C D

reprex package (v0.3.0) 于 2019 年 11 月 12 日创建

【问题讨论】:

  • 对于逐行操作,请参阅purrr::pmap()
  • 我试过purrr::pmap()但也无济于事。 @aosmith

标签: r purrr


【解决方案1】:

在基础 R

您可以使用基础 r 中的 apply 函数。此函数将函数应用于数组的行或列。

apply(a_df, 1, cut_modif)

使用purrr::map

当您将数据框作为参数传递给purrr::map 进行迭代时,迭代是按列而不是按行完成的。所以,做你想做的事,我只看到两个选项:

  1. 将数据框重新调整为整洁的格式,其中值在行中,变量在列中
a_df = data.frame(t(a_matrix))

map(
  a_df,
  cut_modif
  )
  1. 稍微修改您的 cut_modf 函数以将行索引用作参数
a_df = data.frame(a_matrix)

cut_modif = function(.df, row) {
  x <- .df[row, ] %>% as.numeric()

  cut(x,
      breaks = quantile(x),
      labels = c("A", "B", "C", "D"),
      include.lowest = T,
      right = T
  )
}

map(
  1:nrow(a_df),
  ~cut_modif(.df = a_df, row = .x)
  )

【讨论】:

  • 嗨,约翰。感谢您的反馈。我知道我可以使用apply,但此时我有兴趣了解为什么它不适用于map。此外,在这种情况下,我也不会得到我想要的。再一次,当我想要原来的 15 列时,我只会得到 2 列。 PS.:我知道我可以转置答案。
  • 这是您所期待的吗?
  • 我承认我期待 - 并且希望 - 更简单的东西。但是您的解决方案有效,并且没有那么复杂。感谢您的贡献。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-19
  • 2022-07-04
相关资源
最近更新 更多