Добавление определенных строк в фрейм данных - PullRequest
1 голос
/ 18 июня 2019

Я пытаюсь добавить конкретную строку кадра данных вместе.

И если не использовать grepl для поиска строк, а затем привязать их к нижней части, я не уверен, есть ли лучший способ сделать это.

это мой ввод df:

input = structure(list(
V1 = c("Sales", "Sales", "Sales", "Sales", "Sales","Sales"),
V2 = c("Johnny", "Meg", "Fred", "Johnny", "Meg", "Fred"),
V3 = c("Australia", "Australia", "Australia", "NZ", "NZ","NZ"), 
V4 = c(154L, 1898L, 175L, 1235L, 23L, 255L)), row.names = c(NA,6L),
 class = "data.frame")

и это мой ожидаемый результат:

structure(list(
V1 = c("Sales", "Sales", "Sales", "Sales", "Sales", 
"Sales", "Sales", "Sales", "Sales", "Sales", "Sales", "Sales"), 
V2 = c("Johnny", "Meg", "Fred", "Johnny", "Meg", "Fred", "Johnny + Fred", 
"Meg + Fred", "Johnny + Meg + Fred", "Johnny + Fred", "Meg + Fred", 
"Johnny + Meg + Fred"), 
V3 = c("Australia", "Australia", "Australia", "NZ",
 "NZ", "NZ", "Australia", "Australia", "Australia", "NZ", "NZ", "NZ"), 
V4 = c(154L, 1898L, 175L, 1235L, 23L, 255L, 329L, 2073L, 2227L, 1490L, 278L, 1513L)),
 class = "data.frame", row.names = c(NA, -12L)
)

Я бы подумал, что есть лучший способ добавить эти строки, которые фильтруют, затем добавляют, а затем объединяют и т. Д.

Может кто-нибудь указать мне правильное направление, что я должен искать?

Ответы [ 2 ]

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

Я решаю проблему, используя combn

Часть ввода данных

input = structure(list(
  V1 = c("Sales", "Sales", "Sales", "Sales", "Sales","Sales"),
  V2 = c("Johnny", "Meg", "Fred", "Johnny", "Meg", "Fred"),
  V3 = c("Australia", "Australia", "Australia", "NZ", "NZ","NZ"), 
  V4 = c(154L, 1898L, 175L, 1235L, 23L, 255L)), row.names = c(NA,6L),
  class = "data.frame")


structure(list(
  V1 = c("Sales", "Sales", "Sales", "Sales", "Sales", 
         "Sales", "Sales", "Sales", "Sales", "Sales", "Sales", "Sales"), 
  V2 = c("Johnny", "Meg", "Fred", "Johnny", "Meg", "Fred", "Johnny + Fred", 
         "Meg + Fred", "Johnny + Meg + Fred", "Johnny + Fred", "Meg + Fred", 
         "Johnny + Meg + Fred"), 
  V3 = c("Australia", "Australia", "Australia", "NZ",
         "NZ", "NZ", "Australia", "Australia", "Australia", "NZ", "NZ", "NZ"), 
  V4 = c(154L, 1898L, 175L, 1235L, 23L, 255L, 329L, 2073L, 2227L, 1490L, 278L, 1513L)),
  class = "data.frame", row.names = c(NA, -12L)
)

Решение

library(dplyr)

TT = unique(input$V2)
> TT
[1] "Johnny" "Meg"    "Fred"  

comb2 = combn(TT,2,simplify = FALSE)
> comb2

 [[1]]
[1] "Johnny" "Meg"   

[[2]]
[1] "Johnny" "Fred"  

[[3]]
[1] "Meg"  "Fred"

comb3 = combn(TT,3,simplify = FALSE)
> comb3
 [[1]]
[1] "Johnny" "Meg"    "Fred"  

result = function(data){
  purrr::map_df(lapply(data,function(x){paste(x,collapse = '|')}), function(x){
    df = input[grepl(x,input$V2),] %>% group_by(V3)%>%summarize(V1= 'Sales',
                                                                V2= paste(V2,collapse = '+'),
                                                                V4= sum(V4))
    return(df)
  }
  )
}

Результат

result(comb2)
# A tibble: 6 x 4
  V3        V1    V2             V4
  <chr>     <chr> <chr>       <int>
1 Australia Sales Johnny+Meg   2052
2 NZ        Sales Johnny+Meg   1258
3 Australia Sales Johnny+Fred   329
4 NZ        Sales Johnny+Fred  1490
5 Australia Sales Meg+Fred     2073
6 NZ        Sales Meg+Fred      278

result(comb3)
# A tibble: 2 x 4
  V3        V1    V2                 V4
  <chr>     <chr> <chr>           <int>
1 Australia Sales Johnny+Meg+Fred  2227
2 NZ        Sales Johnny+Meg+Fred  1513


finalResult = bind_rows(A,B,input) %>%
  select(V1,V2,V3,V4) %>% filter(! V2 %in% c('Johnny+Meg'))

> finalResult 
# A tibble: 12 x 4
   V1    V2              V3           V4
   <chr> <chr>           <chr>     <int>
 1 Sales Johnny+Fred     Australia   329
 2 Sales Johnny+Fred     NZ         1490
 3 Sales Meg+Fred        Australia  2073
 4 Sales Meg+Fred        NZ          278
 5 Sales Johnny+Meg+Fred Australia  2227
 6 Sales Johnny+Meg+Fred NZ         1513
 7 Sales Johnny          Australia   154
 8 Sales Meg             Australia  1898
 9 Sales Fred            Australia   175
10 Sales Johnny          NZ         1235
11 Sales Meg             NZ           23
12 Sales Fred            NZ          255
0 голосов
/ 18 июня 2019

Используя tidyverse, мы можем сначала split фрейм данных на основе V3, затем создать комбинацию имен и добавить sum, чтобы создать новый тиббл и связать его с исходным фреймом данных.

library(tidyverse)

input %>%
     bind_rows(input %>%
                   group_split(V3) %>%
                   map_dfr(function(x) map_dfr(2:nrow(x), ~tibble(
                           V1 = first(x$V1), 
                           V2 = combn(x$V2, ., paste, collapse = " + "), 
                           V3 = first(x$V3),
                           V4 = combn(x$V4, .,sum)) %>% 
                           filter(grepl("\\bFred\\b", V2)))))


#      V1                  V2        V3   V4
#1  Sales              Johnny Australia  154
#2  Sales                 Meg Australia 1898
#3  Sales                Fred Australia  175
#4  Sales              Johnny        NZ 1235
#5  Sales                 Meg        NZ   23
#6  Sales                Fred        NZ  255
#7  Sales       Johnny + Fred Australia  329
#8  Sales          Meg + Fred Australia 2073
#9  Sales Johnny + Meg + Fred Australia 2227
#10 Sales       Johnny + Fred        NZ 1490
#11 Sales          Meg + Fred        NZ  278
#12 Sales Johnny + Meg + Fred        NZ 1513

Используя ту же логику, но в базе R, мы можем сделать

rbind(input, do.call(rbind, lapply(split(input, input$V3), function(x) 
             do.call(rbind, lapply(2:nrow(x), function(y)
        subset(data.frame(V1 = x$V1[1],
                          V2 = combn(x$V2, y, paste, collapse = " + "), 
                          V3 = x$V3[1],
                          V4 = combn(x$V4, y, sum)), 
         grepl("\\bFred\\b", V2)))))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...