Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用apply将R循环转换为函数形式_R_Functional Programming_Apply - Fatal编程技术网

使用apply将R循环转换为函数形式

使用apply将R循环转换为函数形式,r,functional-programming,apply,R,Functional Programming,Apply,我已经编写了一些R代码来解析字符串,计算子字符串的出现次数,然后填充子字符串计数表。它工作得很好,但在我使用的实际数据(相当大)上速度非常慢,我知道这是因为我使用的是循环,而不是apply系列的函数。我一直在尝试将此代码转换为函数形式,但我运气不佳,有人能帮我吗?我最大的问题是我无法找到一种方法来使用列名匹配apply构造中的值。下面是一些玩具数据的代码: #Create toy data, list of unique substrings code_frame<-matrix(c(c(

我已经编写了一些R代码来解析字符串,计算子字符串的出现次数,然后填充子字符串计数表。它工作得很好,但在我使用的实际数据(相当大)上速度非常慢,我知道这是因为我使用的是循环,而不是apply系列的函数。我一直在尝试将此代码转换为函数形式,但我运气不佳,有人能帮我吗?我最大的问题是我无法找到一种方法来使用列名匹配apply构造中的值。下面是一些玩具数据的代码:

#Create toy data, list of unique substrings
code_frame<-matrix(c(c('a|a|b|c|d'),c('a|b|b|c|c'),c('a|b|c|d|d')),nrow=3,ncol=1)   
all_codes_list<-c('a','b','c','d')

#create data frame with a column for each code and a row for each job
code_count<-as.data.frame(matrix(0, ncol = length(all_codes_list), nrow = nrow(code_frame)))
colnames(code_count)<-all_codes_list

#fill in the code_count data frame with entries where codes occur
for(i in 1:nrow(code_frame)){
    test_string<-strsplit(code_frame[i,1],split="|",fixed=TRUE)[[1]]
    for(j in test_string){
        for(g in 1:ncol(code_count)){
            if(j == all_codes_list[g]){
                code_count[i,g]<-code_count[i,g]+1
                }
            }
        }
    }
#创建玩具数据,唯一子字符串列表
code_frame有一个非常适合这种情况的工具,应该是非常快速和少量的编码,称为
mtabulate

library(qdap)    
mtabulate(strsplit(code_frame, "\\|"))

##   a b c d
## 1 2 1 1 1
## 2 1 2 2 0
## 3 1 1 1 2
基本上,它获取向量列表(从strsplit输出)并为每个向量生成一行列表信息

编辑: 如果速度真的是你的事情,那么以下是1000次复制(在Win 7机器上)的基准测试:

和视觉输出:

A
base
备选方案:

df <- read.table(text = code_frame, sep = "|")

tt <- apply(df, 1, function(x){
  x2 <- factor(x, levels = letters[1:4])
  table(x2)
  })

t(tt) 

#      a b c d
# [1,] 2 1 1 1
# [2,] 1 2 2 0
# [3,] 1 1 1 2

dfA一行,分为三行:

do.call(rbind,
        lapply(strsplit(code_frame[,1], "|", fixed=TRUE),
               function(x) table(factor(x, levels=all_codes_list))))

请注意,
strsplit
是矢量化的,因此不需要在所有行上都使用外部循环。您的内部循环基本上是统计每个代码的出现次数,这是
的一个应用程序。最后,
do.call(rbind,*)
是将行列表转换为单个数据帧的标准习惯用法。

这真的是代码帧的样子吗?你如何回答将取决于我给出的建议。是的,基本上。这是一个管道分隔的长字符串,我需要将其分解为子字符串。这不是它的创建方式(它已经从我从中提取它的数据库中形成了一个长管道delim str),但是它的形式是相同的。这很酷。感谢所有的回复,我一定会记住“table”函数。感谢您的
mtabulate
函数和计时,+1!
do.call(rbind,
        lapply(strsplit(code_frame[,1], "|", fixed=TRUE),
               function(x) table(factor(x, levels=all_codes_list))))