如何使用 R 中的条件语句将数据帧拆分为多个数据帧

Posted

技术标签:

【中文标题】如何使用 R 中的条件语句将数据帧拆分为多个数据帧【英文标题】:how to split a data frame into multiple data frames using a conditional statement in R 【发布时间】:2014-01-25 20:29:07 【问题描述】:

我的数据如下所示:

time <- c(1:20)
temp <- c(2,3,4,5,6,2,3,4,5,6,2,3,4,5,6,2,3,4,5,6)
data <- data.frame(time,temp)

这是我的数据的一个非常基本的表示。如果您绘制此图,您可以很容易地看到有 4 组向上倾斜的数据。我想将原始数据框拆分为这 4 个“子集”,以便可以对它们进行计算,例如“mean”、“max”、“min”和“std”。我想使用 split() 但它只会根据因子级别进行拆分。我希望能够为 split 提供条件语句,例如 split if: diff(data$temp) &gt; -2

我的问题实际上比这复杂得多,但是有没有像split 这样的函数可以让我根据条件语句创建新的数据框?与基于因子水平的拆分相反。

谢谢大家!

【问题讨论】:

【参考方案1】:

诀窍是将条件语句转换为可以解释为因素的内容。在这个特定的例子中:

tmp <- c(1,diff(data[[2]]))
#  [1]  1  1  1  1  1 -4  1  1  1  1 -4  1  1  1  1 -4  1  1  1  1
tmp2 <- tmp < 0
# [1] FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE
# [13] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
tmp3 <- cumsum(tmp2)
#  [1] 0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
split(data, tmp3)
# $`0`
#   time temp
# 1    1    2
# 2    2    3
# 3    3    4
# 4    4    5
# 5    5    6
# 
# $`1`
#    time temp
# 6     6    2
# 7     7    3
# 8     8    4
# 9     9    5
# 10   10    6
# 
# $`2`
#    time temp
# 11   11    2
# 12   12    3
# 13   13    4
# 14   14    5
# 15   15    6
# 
# $`3`
#    time temp
# 16   16    2
# 17   17    3
# 18   18    4
# 19   19    5
# 20   20    6

【讨论】:

谢谢,这可能是我可以使用的解决方案。正如我所说,我的数据要复杂得多,但这让我想到了一种可能的处理方法。 好的,谢谢!现在你能告诉我为什么当我尝试在这个列表上执行你的 split() 建议创建的任何操作时,我只得到第一列返回(在这个例子中是时间)?我需要对每一部分进行子集化,当我这样做时,我只会得到第一列。我尝试使用 for 循环将每个部分变成一个数据框,我认为这可能会有所帮助,而且只有第一列。您知道这里发生了什么,或者对如何成功跟踪和执行每件作品的操作有什么建议吗?谢谢! @user1667477 假设您使用sp &lt;- split(data, tmp3)。然后您可以通过sp[[1]] 之类的方式访问列表的成员,并使用lapply 对每个列表元素进行操作。如果您需要进一步的帮助,请尝试发布另一个引用此问题和答案的问题。【参考方案2】:

如果您的数据表现不佳,您可以使用cut() 创建分类变量。唯一的“问题”是它是 100% 手动的。

time <- c(1:200)
temp <- (time %% 51) * (-1)^(time %/% 51) + rnorm(200)
data <- data.frame(time,temp) 

layout(matrix(c(1, 1, 2, 2, 3, 4, 5 ,6), nrow=2))
plot(data, main='All data')

time2 <- cut(time, c(0, 50, 101, 152, 200))
plot(data, col=time2, main='All data, by time2')
data2 <- split(data, time2)

for (i in 1:4) 
 plot(data2[[i]], main=names(data2)[i])

编辑:

现在是 100% 自动化流程:

time <- c(1:200)
temp <- (time %% 51) * (-1)^(time %/% 51) + rnorm(200)
data <- data.frame(time,temp) 

layout(matrix(c(1, 1, 2, 2, 3, 4, 5 ,6), nrow=2))
plot(data, main='All data')


tol <- 10 # Here you set the minimum value to consider as a structural break
time2 <- cut(time, c(0, which(abs(diff(data$temp)) >= tol), max(time)), rigth=FALSE)

plot(data, col=time2, main='All data, by time2')
data2 <- split(data, time2)

for (i in 1:4) 
 plot(data2[[i]], main=names(data2)[i])

【讨论】:

是的,谢谢,但我需要这个自动化,有很多数据可以手动完成。 好的,现在它是 100% 自动的。 嘿,谢谢!这可能会导致一些可行的方法,但现在我在实施这个修复时遇到了麻烦,因为我的时间数据是类:POSIXt,当它尝试 cut() 时出现错误。你知道解决这个问题的任何方法吗? 是的,我已经尝试了很多事情,但我一直收到错误消息:“cut.POSIXt() 中的错误,'breaks' 的无效规范”如果您需要更多信息来帮助我解决这个问题,请告诉我。谢谢。 使用蓝魔导师的思路,将time2 &lt;- cut(time, c(0, which(abs(diff(data$temp)) &gt;= tol), max(time)), rigth=FALSE)替换为time2 &lt;- cumsum(c(0, abs(diff(data$temp)) &gt;= tol))

以上是关于如何使用 R 中的条件语句将数据帧拆分为多个数据帧的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据帧拆分为多个数据帧,其中每个数据帧包含相等但随机的数据[重复]

如何根据字节大小拆分熊猫数据帧

Scala:我如何根据行数将数据帧拆分为多个 csv 文件

将数据帧列表拆分为多个数据帧

如何根据原始数据帧中的总行数将数据帧拆分为两个数据帧

根据 NaN 值将数据帧拆分为多个数据帧