嵌套for函数循环并套用

时间:2019-12-25 15:38:14

标签: r

我正在努力编写函数并为嵌套的for循环调用代码。下面的代码可以很容易地放在for循环中,并且我的函数也可以运行。但是我试图避免在我的函数中使用for循环并进行不适。请帮助我使用lapply创建函数及其相应的调用代码

带有for循环的代码:

df <- data.frame(actual=c("reaok_oc giade_len","reaok_oc giade_len reaok_oc giade_len"),
                  Predicted = c("giade_len","reaok_oc giade_len reaok_oc giade_len"))

df[] <- lapply(df, as.character)
str(df)

all_acc<-NULL
for(s in 1:nrow(df)){
  sub_df1<-df[s,]
  actual_words<-unlist(strsplit(sub_df1$actual," "))
  all_count<-0
  for(g in 1:length(actual_words)){
    count_len<-ifelse(grep(actual_words[g],sub_df1$Predicted),1,0)
    all_count<-sum(all_count,count_len)
  }
  sub_acc<-all_count/length(actual_words)
  all_acc<-c(all_acc,sub_acc)
}

df$trans_acc<-all_acc
sensitivity=sum(df$trans_acc)/nrow(df)
sensitivity

在函数中使用lapply调用代码来处理代码:


a1 <- function(df){
  sub_df1<-df[s,]
  actual_words<-unlist(strsplit(sub_df1$actual," "))
  all_count<-0
}

a2 <- function(df){
  count_len<-ifelse(grep(actual_words[g],sub_df1$Predicted),1,0)
  all_count<-sum(all_count,count_len)
  sub_acc<-all_count/length(actual_words)
  all_acc<-c(all_acc,sub_acc)
df$trans_acc<-all_acc
sensitivity=sum(df$trans_acc)/nrow(df)
sensitivity
}


lapply(1:nrow(df) FUN = a1, lapply(1:length(actual_words) FUN = a2, actual_words,sub_aa1))

2 个答案:

答案 0 :(得分:4)

在基R中,通常最好找到“向量化”(仅一个R函数调用)而不是“迭代”(每个元素一个调用)的解决方案。例如

for(s in 1:nrow(df)){
    sub_df1<-df[s,]
    actual_words<-unlist(strsplit(sub_df1$actual," "))
    ...

涉及到nrow(df)的{​​{1}}调用,但是

strsplit()

只涉及一个,但是执行相同的转换。

我也认为当你说

actual <- strsplit(df$actual, " ")

您实际上只是在寻找实际单词和预测单词之间的完全匹配。这样您就可以分割预测的单词

    for(g in 1:length(actual_words)){
        count_len<-ifelse(grep(actual_words[g],sub_df1$Predicted),1,0)
        all_count<-sum(all_count,count_len)
    }

并计算predicted <- strsplit(df$Predicted, " ") ,依此类推。将此作为函数编写

sum(actual[[1]] %in% predicted[[1]])

“ for”循环可能会遍历实际和预测的每个元素

actual_in_predicted <- function(actual, predicted) {
    sum(actual %in% predicted)
}

但是最好使用all_count <- integer() for (i in 1:nrow(df)) all_count[[i]] <- actual_in_predicted(actual[[i]], predicted[[i]]) 遍历mapply()actual的每个元素

predicted

您的变量all_count <- mapply(actual_in_predicted, actual, predicted) 是此向量的矢量除以每次比较中的实际单词数

all_acc

完整的修订代码使用一个函数来比较每行中的实际单词和预测单词,并使用循环遍历每行。

all_acc <- all_count / lengths(actual)

答案 1 :(得分:2)

也许我们可以使用separate_rows

library(dplyr)
library(tidyr)
library(stringr)
df %>%
   separate_rows(actual, sep="_") %>%
   summarise(perc = mean(str_detect(Predicted, actual)))
#  perc
#1 0.75

它可以包装成一个函数

f1 <- function(data, act, pred) {
   data %>%
       separate_rows({{act}}, sep="_") %>%
       summarise(perc = mean(str_detect({{pred}}, {{act}})))
 }
f1(df, actual, Predicted)
#   perc
#1 0.75