在R中循环字符串

4

我希望您能告诉我代码中的问题,而不是直接给出解决方案。我想循环遍历一些字符串,我的数据如下:

id    source    transaction

 1     a > b       6 > 0
 2     J > k       5
 3     b > c       4 > 0

我有一个列表,希望遍历此列表并找到包含该元素的行,并计算平均值。

mylist <- c ("a", "b") 

所以我期望列表中的一个元素的输出结果是

source  avg
a        6 
b        2      

我不知道如何循环遍历列表并将它们发送到csv文件中。我尝试了以下代码:
mylist <- c( "a", "b" )

for(i in mylist)
{

  KeepData <- df [grepl(i, df$source), ]
   KeepData <- cSplit(KeepData, "transaction", ">", "long")

  avg<- mean(KeepData$transactions)
  result <- list(i,avg )

  write.table(result ,file="C:/Users.csv", append=TRUE,sep=",",col.names=FALSE,row.names=FALSE)

}

但是以下警告信息给我返回了“NA”结果:

警告信息:1: 在 mean.default(KeepData$transactions) 中:
参数不是数字或逻辑值:返回 NA 2: 在 mean.default(KeepData$transactions) 中:
参数不是数字或逻辑值:返回 NA


你确定新数据的期望均值是正确的吗? - akrun
1
for循环的一个问题是检查cSplit和上面的grepl的输出。对于每个步骤使用print,你就会明白原因了。在这里,cSplit之后transaction列被复制了,而且它不是transactions - akrun
1个回答

3
我们可以使用cSplit函数将源数据进行拆分并转换为“长格式”,然后按照“source”进行分组,使用data.table的方法获取“transaction”的平均值并指定“i”。请保留HTML标记。
library(splitstackshape)
cSplit(df1, "source", " > ", "long")[source %in% mylist, .(avg = mean(transaction)), source]
#   source avg
#1:      a   6
#2:      b   5

另一种选择是使用tidyr中的separate_rows将数据转换为“长”格式,然后使用dplyr方法在按“source”分组后summarise

library(tidyr)
library(dplyr)
separate_rows(df1, source) %>%
        filter(source %in% mylist) %>%
        group_by(source) %>% 
        summarise(avg  = mean(transaction))

更新

对于新的数据集('df2'),我们需要将两列拆分为“长”格式,然后按“来源”分组获取“交易”的平均值

cSplit(df2, 2:3,  " > ", "long")[source %in% my_list, .(avg = mean(transaction)), source]
#   source avg
#1:      a   6
#2:      b   2

for循环可以被修改为

for(i in mylist) {
   KeepData <-  cSplit(df2, 2:3,  ">", "long")
   KeepData <- KeepData[grepl(i, source)]
   avg<- mean(KeepData$transaction)
   result <- list(i,avg )
   print(result)
   write.table(result ,file="C:/Users.csv", 
             append=TRUE,sep=",",col.names=FALSE,row.names=FALSE)
 }
#[[1]]
#[1] "a"

#[[2]]
#[1] 6

#[[1]]
#[1] "b"

#[[2]]
#[1] 2

数据

df1 <- structure(list(id = 1:3, source = c("a > b", "J > k", "b > c"
 ), transaction = c(6L, 5L, 4L)), .Names = c("id", "source", "transaction"
), class = "data.frame", row.names = c(NA, -3L))


df2 <- structure(list(id = 1:3, source = c("a > b", "J > k", "b > c"
), transaction = c("6 > 0", "5", "4 > 0")), .Names = c("id", 
"source", "transaction"), class = "data.frame", row.names = c(NA, 
-3L))

谢谢@akrun,这个例子可以工作,但我主要想知道这段代码有什么问题,以便在我的情况下应用。在我的工作中,交易列也像2>3一样。我该如何应用它? - MFR
@MFR 你是说交易列是字符类吗?从评论中不清楚。 - akrun
谢谢@akrun,source !%in% my_list计算的是不包含在我的列表中的源的平均值吗? - MFR
@MFR 你必须使用 !source %in% my_list - akrun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接