如何将 lapply 迭代函数的输出合并到 1 个数据帧中?

How to merge output of lapply iterated function into 1 dataframe?

我有一个函数 responses 来处理一些子集到不同数据帧中的数据。

我也有这些数据帧的列表partylist

我正在尝试使用 lapply 遍历数据子集列表,然后将结果收集到一个数据框中。

#Function called "response"

response <- function(dat, p){
    y = select(dat, p)
    sums = table(y)
    sums_df = as.data.frame(sums)
    sums_df$rfreq = (sums_df$Freq/sum(sums_df$Freq))*100
    sums_df$rfreq = round(sums_df$rfreq, digits = 0)
    sums_df = sums_df[1:4, c(1,3)]
  return(sums_df)  
}

#Code for iterating through the list of dfs.

lapply(partylist, response, p = "f78a")

#Output:

[[1]]
                    y rfreq
1      Instämmer helt    29
2    Instämmer delvis    40
3  Instämmer knappast     6
4 Instämmer inte alls     2

[[2]]
                    y rfreq
1      Instämmer helt    32
2    Instämmer delvis    38
3  Instämmer knappast     8
4 Instämmer inte alls     2

任何人都可以建议我该怎么做吗?

一个类似的问题was asked here,但从未得到回答。

您的数据:

outputs <- list(structure(list(y = c("Instämmer helt", "Instämmer delvis", 
"Instämmer knappast", "Instämmer inte alls"), 
 rfreq = c(29L, 40L, 6L, 2L)), class = "data.frame", 
 row.names = c(NA, -4L)), 
 structure(list(y = c("Instämmer helt", "Instämmer delvis", 
                         "Instämmer knappast", "Instämmer inte alls"), 
 rfreq = c(32L, 38L, 8L, 2L)), class = "data.frame", 
 row.names = c(NA, -4L)))

Reduce可以用来添加列,正如@Allan Cameron所说,如果结合merge,它也可以用来绑定rfreq列而不重复y 列。

Reduce(function(df1,df2) merge(df1,df2, by = "y", suffixes = 1:2), outputs)

#                   y rfreq1 rfreq2
#1    Instämmer delvis     40     38
#2      Instämmer helt     29     32
#3 Instämmer inte alls      2      2
#4  Instämmer knappast      6      8

这种方法可以应用于包含两个以上元素的列表,但列名重复。后缀 3,4,... 不会自动添加到结果列名称中。

# Creating two more elements so now `outputs` has four elements
outputs[[3]] <- outputs[[1]]
outputs[[4]] <- outputs[[2]]

# Exactly same code

Reduce(function(df1,df2) merge(df1,df2, by = "y", suffixes = 1:2), outputs) 

# The result:
#                   y rfreq1 rfreq2 rfreq1 rfreq2
#1    Instämmer delvis     40     38     40     38
#2      Instämmer helt     29     32     29     32
#3 Instämmer inte alls      2      2      2      2
#4  Instämmer knappast      6      8      6      8
#Warning message:
#In merge.data.frame(df1, df2, by = "y", suffixes = 1:2) :
#  column names ‘rfreq1’, ‘rfreq2’ are duplicated in the result

更新

至于为什么在结果数据框中交换行顺序,这是因为 merge 函数默认按字典顺序对合并的行进行排序,如其文档中所述:

The rows are by default lexicographically sorted on the common columns, but for sort = FALSE are in an unspecified order.

为了避免这种默认行为,我们可以设置 sort = FALSE

Reduce(function(df1,df2) merge(df1,df2, by = "y", suffixes = 1:2, sort = FALSE), outputs)

#                    y rfreq1 rfreq2 rfreq1 rfreq2
#1      Instämmer helt     29     32     29     32
#2    Instämmer delvis     40     38     40     38
#3  Instämmer knappast      6      8      6      8
#4 Instämmer inte alls      2      2      2      2
#Warning message:
#In merge.data.frame(df1, df2, by = "y", suffixes = 1:2, sort = FALSE) :
#  column names ‘rfreq1’, ‘rfreq2’ are duplicated in the result