Как уменьшить кадр данных в одну строку с векторами - PullRequest
4 голосов
/ 03 апреля 2020

У меня есть этот DF

  email       date      user_ipaddress       other data    
1 x@bla.com 2020-03-24  177.95.75.230         xxxx
2 x@bla.com 2020-04-02  177.139.49.93         yyyy
3 x@bla.com 2020-04-02  177.139.49.93         zzzz

, и я хочу преобразовать эти данные в форму, в которой они будут храниться

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

  email       date      user_ipaddress                       other data    
1 x@bla.com 2020-04-02  c('177.95.75.230','177.139.49.93')   c('xxxx','yyyy','zzzz') 

, если бы кто-то мог помочь мне только в том случае, если есть только один адрес электронной почты, это спасло бы мою жизнь, но я чувствую я могу решить всю проблему

используя

ipadreessVec<-Reduce(append,x =df$network_userid) 

Я могу получить свой вектор c('177.95.75.230','177.139.49.93'), но если я попытаюсь сделать

newdf$network_userid<-a

, я получу

Error in `$<-.data.frame`(`*tmp*`, network_userid, value = c("20562206-f557-48a3-861b-5d1e18524bbb",  : 
  replacement has 3 rows, data has 1

любой ответ, который делает меня go на шаг вперед, получит одобрение, даже если он не решит все проблемы.

Ответы [ 4 ]

3 голосов
/ 03 апреля 2020

Возможно, я вас неправильно понимаю, и более вероятно, что вы хотите что-то вроде шоу @akrun, но, интерпретируя вас буквально, вы можете захотеть что-то, используя dput:

as.data.frame(lapply(df, function(x) capture.output(dput(unique(x)))))
#>         email                          date                      user_ipaddress
#> 1 "x@bla.com" c("2020-03-24", "2020-04-02") c("177.95.75.230", "177.139.49.93")
#>                       other
#> 1 c("xxxx", "yyyy", "zzzz")

3 голосов
/ 03 апреля 2020
library('data.table')

по электронной почте и дата:

setDT(df)[, .(user_ipaddress = paste0(user_ipaddress, collapse = ","),
              other = paste0(other_data, collapse = ",")), by = .(email, date)]

#       email       date              user_ipaddress     other
# 1: x@bla.com 2020-03-24               177.95.75.230      xxxx
# 2: x@bla.com 2020-04-02 177.139.49.93,177.139.49.93 yyyy,zzzz

только по электронной почте:

setDT(df)[, .(date = paste0(date, collapse = ","),
              user_ipaddress = paste0(user_ipaddress, collapse = ","),
              other = paste0(other_data, collapse = ",")), by = .(email)]

#        email                             date                            user_ipaddress          other
# 1: x@bla.com 2020-03-24,2020-04-02,2020-04-02 177.95.75.230,177.139.49.93,177.139.49.93 xxxx,yyyy,zzzz

Данные:

df <- read.table(text='email       date      user_ipaddress       other_data    
1 x@bla.com 2020-03-24  177.95.75.230         xxxx
                 2 x@bla.com 2020-04-02  177.139.49.93         yyyy
                 3 x@bla.com 2020-04-02  177.139.49.93         zzzz', header = TRUE, stringsAsFactors = FALSE)
3 голосов
/ 03 апреля 2020

Мы можем создать столбец list, сгруппированный по 'email', 'date'

library(dplyr)
DF %>% 
    group_by(email, date) %>%
    summarise_all(list)
# A tibble: 2 x 4
# Groups:   email [1]
#  email     date       user_ipaddress otherdata
#  <chr>     <chr>      <list>         <list>   
#1 x@bla.com 2020-03-24 <chr [1]>      <chr [1]>
#2 x@bla.com 2020-04-02 <chr [2]>      <chr [2]>

Или в версии devel используйте across с summarise

DF %>%
   group_by(email, date) %>% 
   summarise(across(everything(), list))
# A tibble: 2 x 4
# Groups:   email [1]
#  email     date       user_ipaddress otherdata
#  <chr>     <chr>      <list>         <list>   
#1 x@bla.com 2020-03-24 <chr [1]>      <chr [1]>
#2 x@bla.com 2020-04-02 <chr [2]>      <chr [2]>

data

DF <- structure(list(email = c("x@bla.com", "x@bla.com", "x@bla.com"
), date = c("2020-03-24", "2020-04-02", "2020-04-02"),
 user_ipaddress = c("177.95.75.230", 
"177.139.49.93", "177.139.49.93"),
otherdata = c("xxxx", "yyyy", 
"zzzz")), class = "data.frame", row.names = c("1", "2", "3"))
2 голосов
/ 03 апреля 2020

Может быть, вы можете попробовать aggregate в базе R:

dfout <- aggregate(.~email,df,FUN = function(x) list(unique(levels(x))))

так, чтобы

> dfout
      email                   date               user_ipaddress       other data
1 x@bla.com 2020-03-24, 2020-04-02 177.139.49.93, 177.95.75.230 xxxx, yyyy, zzzz

ДАННЫЕ

df <-  structure(list(email = c("x@bla.com", "x@bla.com", "x@bla.com"
), date = c("2020-03-24", "2020-04-02", "2020-04-02"), user_ipaddress = c("177.95.75.230", 
"177.139.49.93", "177.139.49.93"), `other data` = c("xxxx", "yyyy", 
"zzzz")), class = "data.frame", row.names = c(NA, -3L))
...