假设我手头有900个数据帧,我希望得到类似于基于每个“类型”的另一列的频率分布。
示例代码makin;
df1 <- as_tibble(iris)
df2 <- slice(df1, 1:7)
df2 <- df2 %>%
mutate(type = 1:7)
这类似于我目前只使用一个数据帧:
df2 %>% select(type, Sepal.Length) %>%
mutate(Count = ifelse(Sepal.Length > 0, 1, 0)) %>%
mutate(Percentage = Count/7)
对于任何行,Sepal.Length = 0,那么我不会计算它(对于该行值,count列将为= 0)。
但是我将有900个数据帧,我将运行此代码,所以我正在考虑通过循环运行它。
理想情况下,如果输入两个数据帧,并且第一行的Sepal.Length值> 0,那么我希望第1行/类型1的计数为2.有没有更好的方法来解决这个问题?如果我确实选择了循环选项,那么有没有办法将所有数据帧组合起来告诉R第1行/第1行有多个&gt; 0值?
答案 0 :(得分:0)
对于您的虹膜示例,您想要的是:
library(tidyverse)
df1 <- as_tibble(iris)
df2 <- slice(df1, 1:7)
df2 <- df2 %>%
mutate(type = 1:7)
group_by(df2, type) %>%
transmute(has_sepal = sum(Sepal.Length > 0))
# A tibble: 7 x 2
# Groups: type [7]
# type has_sepal
# <int> <int>
# 1 1 1
# 2 2 1
# 3 3 1
# 4 4 1
# 5 5 1
# 6 6 1
# 7 7 1
要做到这一点超过900个数据帧...如果你想要这个在虹膜,硬编码上工作。熟悉使用tidyverse评估编写函数的人可以为你编写更通用的版本,但这仍然在我的待办事项列表中。
f_fill_in_blank_first <- function(tib){
# hard code the var1 and var2
group_by(tib, <var1>) %>%
transmute(var1_not_zero = sum(<var 1> != 0))
}
f_iris <- function(tib)
group_by(tib, type) %>%
transmute(var1_not_zero = sum(Sepal.Length != 0)
}
根据你的900个数据帧的结构,你可以使用这个函数进行vapply(编辑,不,不是这个函数,重构因此,如果你想要使用这个函数,它会生成一个命名的原子向量)将整个事物放入一个数组,然后使用apply和sum折叠其中一个维度
答案 1 :(得分:0)
如果你想保留你的代码:
df2 %>% select(type, Sepal.Length) %>%
mutate(Count = ifelse(Sepal.Length > 0, 1, 0)) %>%
mutate(Percentage = Count/7)
您可以将其包装到函数(add_a_count
)中:
library(tidyverse)
df1 <- as_tibble(iris)
df2 <- df1 %>%
mutate(type = nrow(df1))
add_a_count = function(df)
{
counted_df = df %>%
select(type, Sepal.Length) %>%
mutate(Count = ifelse(Sepal.Length > 0, 1, 0),
Percentage = Count/7)
return(counted_df)
}
我使用以下函数生成100个重复的测试df2
:
duplicate_df = function(df, no_duplicates)
{
tmp_df_list = list()
for(i in c(1:no_duplicates))
{
print(paste0("Duplicate ", i, " generated."))
tmp_df_list[[i]] = df
}
return(tmp_df_list)
}
data_frames_list = duplicate_df(df = df2, no_duplicates = 100)
并将其与lapply
:counted_data_frames = lapply(data_frames_list, add_a_count)
列表counted_data_frames
可以相对容易地被操作(如果你想要一个非列表输出,你可以使用另一个apply
函数)。这可能不是最快的方法,但它很简单。
修改强>
您可以通过循环遍历数据框列表来获取Counts
列。新数据框counts_data_frame
包含所有计数,每列都是一个原始数据框的计数:
counts_data_frame = data.frame(type = seq(from = 1, to = nrow(df2)))
for(i in c(1:length(counted_data_frames)))
{
counts_data_frame = cbind(counts_data_frame, as.vector(counted_data_frames[[i]]["Count"]))
}
当循环遍历这个新数据框的行时,您可以总结您的计数并获得绘图计数的向量:
counts_summarised = vector(length = nrow(counts_data_frame))
for(i in c(1:nrow(counts_data_frame)))
{
counts_summarised[i] = sum(counts_data_frame[i, 2:ncol(counts_data_frame)])
}
plot(counts_summarised, ylab = "Counts", xlab = "Type")
答案 2 :(得分:0)
在此解决方案中,我将向您展示如何:
具体来说,我使用lapply()
来循环data.frame
,使用data.frame
将列表转换为enframe()
,并使用unnest()
取消值列,并pct
使用type
传播spread()
。
让我们先创建一个可以使用的数据。
library(tidyverse)
# create a list
datlist <- list()
# this list will contain ten data frames with
# a sample with up to 8 0's and 20 random uniforms as observations
for (i in seq_len(10)){
datlist[[i]] = data.frame(x = sample(c(sample(c(0,1,2,3,4), 8, replace = T), runif(20,0,10))))
}
# name each element of the list datlist
name_element <- LETTERS[1:10]
datlist <- set_names(datlist, name_element)
# save each file separately
mapply(write.csv, datlist, file=paste0(names(datlist), '.csv'), row.names = FALSE)
以下将import your data into R and store them as data.frame
s in a list。
# import all csv files in the folder into separate data frames in the temp list
temp <- list.files(pattern = "*.csv")
myfiles <- lapply(temp, read.csv)
如果我们假设每个文件包含相同的变量,则以下将按类型计算百分比。
# Calculate the frequency and relative distributions
lapply(myfiles,
function(varname) mutate(varname, type = if_else(x == 0, 0, 1)) %>%
group_by(type) %>% summarise(n = n()) %>%
mutate(pct = n / sum(n))
) %>%
enframe() %>% # convert the list into a data.frame
unnest(value) %>% # unnest the values
spread(type, pct) # spread the values by type
# A tibble: 17 x 4
name n `0` `1`
<int> <int> <dbl> <dbl>
1 1 3 0.107 NA
2 1 25 NA 0.893
3 2 28 NA 1.00
4 3 1 0.0357 NA
5 3 27 NA 0.964
6 4 2 0.0714 NA
7 4 26 NA 0.929
8 5 28 NA 1.00
9 6 28 NA 1.00
10 7 2 0.0714 NA
11 7 26 NA 0.929
12 8 3 0.107 NA
13 8 25 NA 0.893
14 9 1 0.0357 NA
15 9 27 NA 0.964
16 10 1 0.0357 NA
17 10 27 NA 0.964