【问题标题】:filtering a dataset dependant on a value within a string根据字符串中的值过滤数据集
【发布时间】:2014-11-27 12:00:33
【问题描述】:

我目前正在使用 Google Analytics 和 R,并且有一个查询希望有人可以帮助我。

我已将数据从 GA 导出到 R 中,并将其放在数据框中以供处理。

我想创建一个 for 循环,该循环遍历我的数据,如果一列包含某个值,则对我的数据框中的多列求和。

例如,我的数据框是这样的

我有一个 ID 列表,它们是单独的 3 位数字,我可以在 for 循环中使用。

我过去的R经验我已经能够过滤列表以便我拥有

data[data$ID == 341,] -> datanew

我找到了一些代码,可以查看字符串中是否有某个字符串会产生布尔值

grepl(value, chars)

有没有办法将这些链接在一起,以便我有一个类似于下面的总和代码

aggregate(cbind(users, conversion)~ID,data=datanew,FUN=sum) -> resultforID

基本上获取该数据并为每 341 添加用户和转化次数..

我希望我已经以最好的方式解释了这一点。

提前致谢

数据表有 3 列。 ID、用户、用户转化以及与 ID 关联的转化。

有些 ID 是独立的,所以 341,有些是 341|246,有些会有三个数字,它们之间用 | 分隔

【问题讨论】:

  • 您将需要组装目标 3dgit 值列表或创建扩展数据框,其中 341|246 等案例被拆分并重复记录。通过粘贴数据图片,您不会在这些部分结交任何朋友。当您可以轻松发布带有可剪切和粘贴的 dput 的测试数据集时,我们中很少有人愿意构建测试数据集。
  • 谢谢,我现在不在电脑上。我确实尝试插入,但它没有。道歉。早上会整理。只是认为复制可能是最简单的方法。你能帮我解决这个问题吗?

标签: r sum filtering analytics


【解决方案1】:
# toy data
mydata = data.frame(ID = c("341|243","341|243","341|242","341","243",
                           "999","111|341|222"),
                    Users = 10:16,
                    Conv = 5:11)

#            ID Users Conv
# 1     341|243    10    5
# 2     341|243    11    6
# 3     341|242    12    7
# 4         341    13    8
# 5         243    14    9
# 6         999    15   10
# 7 111|341|222    16   11

# are you looking for something like below:
# presume you just want to filter those IDs have 341.
library(dplyr)
mydata[grep("341",mydata$ID),] %>%
  group_by(ID) %>%
  summarise_each(funs(sum))

#            ID Users Conv
# 1 111|341|222    16   11
# 2         341    13    8
# 3     341|242    12    7
# 4     341|243    21   11

【讨论】:

  • 谢谢。我已经运行了它并且它有效,但理想情况下,我希望它像 Ananda 所做的那样,将每一个分开和总结。再次感谢
【解决方案2】:

如果我正确理解您的问题,您可能需要查看我的“splitstackshape”包中的cSplit

使用@KFB 的示例数据(希望能代表您的实际数据),尝试:

library(splitstackshape)
cSplit(mydata, "ID", "|", "long")[, lapply(.SD, sum), by = ID]
#     ID Users Conv
# 1: 341    62   37
# 2: 243    35   20
# 3: 242    12    7
# 4: 999    15   10
# 5: 111    16   11
# 6: 222    16   11

或者,在 Hadleyverse 中,您可以同时使用“dplyr”和“tidyr”,如下所示:

library(dplyr)
library(tidyr)
mydata %>% 
  transform(ID = strsplit(as.character(ID), "|", fixed = TRUE)) %>% 
  unnest(ID) %>% 
  group_by(ID) %>% 
  summarise_each(funs(sum))
# Source: local data frame [6 x 3]
# 
#    ID Users Conv
# 1 111    16   11
# 2 222    16   11
# 3 242    12    7
# 4 243    35   20
# 5 341    62   37
# 6 999    15   10

【讨论】:

  • 我真的不知道他们想要什么
  • 嗨,就您所写的内容而言,这似乎是正确的。我很感激。但是,当我运行您编写的代码时,我在 function_list[[i]](value) 中收到以下错误错误:找不到函数“unnest”
  • @Gareth,你需要最新的tidyr 包。请做install.packages("devtools"); devtools::install_github("hadley/tidyr")
  • @KFB 谢谢我已经这样做了,但 tidyr 将无法安装,我收到错误提示需要下载 rtools,我现在无法使用 rshiny 中的安装包按钮安装包,因为它希望我这样做创建一个文件夹(过去没有这个问题),当我单击“是”时,它只会重新触发相同的消息。它是一台工作电脑,所以不知道它是否与权限有关。感谢您的帮助
【解决方案3】:

我认为这应该可行:

library(dplyr)
sumdf <- yourdf %>%
           group_by(ID) %>%
           summarise_each(funs(sum))

我不清楚你的 ID 列的结构,但如果你只需要获取数字,你可以试试这个:

library(tidyr)
newdf <- separate(yourdf, ID, c('id1', 'id2'), '|') %>%
         filter(id1 == 341)  # optional if you just want one ID

【讨论】:

    【解决方案4】:

    这里有两个答案。第一个是使用子集,第二个是使用字符串的“grep”

    初始运行

    x1<-sample(1:4,10,replace=TRUE)
    x2<-sample(10:40,10)
    x3<-sample(10:40,10)
    
    dat<-as.data.frame(cbind(x1,x2,x3))
    
    for(i in unique(dat$x1)) {
        dat1<-subset(dat,subset=x1==i)
        z<-(aggregate(.~x1,data=dat1,FUN=sum))
        assign(paste0('x1',i),z)
    }
    

    使用 GREP

    x1<-sample(letters[1:3],10,replace=TRUE)
    x2<-sample(10:40,10)
    x3<-sample(10:40,10)
    
    dat<-as.data.frame(cbind(x1,x2,x3))
    
    for(i in unique(dat$x1)) {
        dat1<-dat[grep(i,dat$x1),]
        z<-(aggregate(.~x1,data=dat1,FUN=sum))
        assign(paste0('x1',i),z) #this will assign separate objects as your aggregates with names based on the string
    }
    

    【讨论】:

      猜你喜欢
      • 2012-12-06
      • 2013-11-25
      • 2017-02-04
      • 2016-05-16
      • 1970-01-01
      • 2021-06-06
      • 2021-06-23
      相关资源
      最近更新 更多