Как выполнить итерацию (функционально) по строкам data.frame в R и обработать их как бы зацикливаясь? - PullRequest
1 голос
/ 07 июня 2019

Существует ли метод типа apply, который позволяет нам перебирать data.frame и обрабатывать строки точно так же, как если бы мы были в цикле?Когда я делаю apply(df, 1, function(row){...}), row, переданный функции функции, НЕ является фактической data.frame строкой.

df = data.frame(A=rnorm(3), B=letters[1:3])

for (i in 1:3)
{
  row = df[i,]
  print(row)
  print(class(row))
  print(typeof(row))
  print(row$A)
  print(row$B)
}

apply(df, 1, function(row)
{
  print(row)
  print(class(row))
  print(typeof(row))
  print(row$A)
  print(row$B)
})
> df = data.frame(A=rnorm(3), B=letters[1:3])
> 
> for (i in 1:3)
+ {
+     row = df[i,]
+     print(row)
+     print(class(row))
+     print(typeof(row))
+     print(row$A)
+     print(row$B)
+ }
          A B
1 0.4179416 a
[1] "data.frame"
[1] "list"
[1] 0.4179416
[1] a
Levels: a b c
        A B
2 1.35868 b
[1] "data.frame"
[1] "list"
[1] 1.35868
[1] b
Levels: a b c
           A B
3 -0.1027877 c
[1] "data.frame"
[1] "list"
[1] -0.1027877
[1] c
Levels: a b c
> 
> apply(df, 1, function(row)
+ {
+     print(row)
+     print(class(row))
+     print(typeof(row))
+     print(row$A)
+     print(row$B)
+ })
           A            B 
" 0.4179416"          "a" 
[1] "character"
[1] "character"
 Show Traceback

 Rerun with Debug
 Error in row$A : $ operator is invalid for atomic vectors 

Редактировать 1

A комментарий кэтот ответ говорит, что apply превращает data.frame в матрицу, так что вы в итоге получаете векторы.Я думаю, что это проблема.Может быть, время для выделенного data.frame итератора?

Редактировать 2

Как указал @thelatemail, это действительно может быть дубликат Для каждой строки в R-кадре данных .

1 Ответ

1 голос
/ 07 июня 2019

Кроме lapply для индексов строк, вы также можете использовать lapply с split. Обратите внимание, что я присваиваю результат, чтобы предотвратить печать списка вывода.

df = data.frame(A=rnorm(3), B=letters[1:3])

row_fun <- function(row) {
  print(row)
  print(class(row))
  print(typeof(row))
  print(row$A)
  print(row$B)
}

test <- lapply(split(df, 1:nrow(df)), row_fun)
#>            A B
#> 1 -0.1566198 a
#> [1] "data.frame"
#> [1] "list"
#> [1] -0.1566198
#> [1] a
#> Levels: a b c
#>            A B
#> 2 -0.2241851 b
#> [1] "data.frame"
#> [1] "list"
#> [1] -0.2241851
#> [1] b
#> Levels: a b c
#>           A B
#> 3 -1.028928 c
#> [1] "data.frame"
#> [1] "list"
#> [1] -1.028928
#> [1] c
#> Levels: a b c

Последняя версия dplyr также предоставляет group_map, который может быть адаптирован для представления строк в виде фрейма данных в одну строку для функции, использующей местоимение .x (вместо вектора, который вы уже могли делать с purrr::pmap. Нам просто нужно создать переменную rowid для группировки. Обратите внимание, что это также приводит к простым data.frame s к tbl_df.

library(tidyverse)
test2 <- df %>%
  rowid_to_column() %>%
  group_by(rowid) %>%
  group_map(~ row_fun(.x))
#> # A tibble: 1 x 2
#>        A B    
#>    <dbl> <fct>
#> 1 -0.157 a    
#> [1] "tbl_df"     "tbl"        "data.frame"
#> [1] "list"
#> [1] -0.1566198
#> [1] a
#> Levels: a b c
#> # A tibble: 1 x 2
#>        A B    
#>    <dbl> <fct>
#> 1 -0.224 b    
#> [1] "tbl_df"     "tbl"        "data.frame"
#> [1] "list"
#> [1] -0.2241851
#> [1] b
#> Levels: a b c
#> # A tibble: 1 x 2
#>       A B    
#>   <dbl> <fct>
#> 1 -1.03 c    
#> [1] "tbl_df"     "tbl"        "data.frame"
#> [1] "list"
#> [1] -1.028928
#> [1] c
#> Levels: a b c

Создано в 2019-06-06 пакетом Представление (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...