假设我有一个看起来像这样的数据
ID A B C
1 X 1 10
1 X 2 10
1 Z 3 15
1 Y 4 12
2 Y 1 15
2 X 2 13
2 X 3 13
2 Y 4 13
3 Y 1 16
3 Y 2 18
3 Y 3 19
3 Y 4 10
Run Code Online (Sandbox Code Playgroud)
我想要将这些值相互比较,所以如果一个ID在一个B变量的周期(从1到4)中改变了它的A变量的值,它就会进入数据帧K,如果它没有,那么它会转到数据框架L.
所以在这个数据集中K看起来像
ID A B C
1 X 1 10
1 X 2 10
1 Z 3 15
1 Y 4 12
2 Y 1 15
2 X 2 13
2 X 3 13
2 Y 4 13
Run Code Online (Sandbox Code Playgroud)
和L看起来像
ID A B C
3 Y 1 16
3 Y 2 18
3 Y 3 19
3 Y 4 10
Run Code Online (Sandbox Code Playgroud)
在嵌套循环和if else语句方面,它可以像下面一样解决
for ( i in 1:length(ID)){
m=0
for (j in 1: length(B)){
ifelse( A[j] == A[j+1],m,m=m+1)
}
ifelse(m=0, L=c[,df[i]], K=c[,df[i]])
}
Run Code Online (Sandbox Code Playgroud)
我在一些帖子中读过R嵌套循环可以用apply和替换outer.如果有人能帮我理解在这种情况下如何使用它.
所以基本上你不需要一个带条件的循环,所有你需要做的就是在(s)的每个循环中通过转换为数值来检查是否存在方差(然后将其转换为逻辑使用!)(我假设它在你的真实数据集中,如果它不是一个因素,你可以在内部使用)然后相应地.例如,对于基数R,我们可以用于这样的任务ABIDAfactorFUN = function(x) length(unique(x))avesplitave
indx <- !with(df, ave(as.numeric(A), ID , FUN = var))
Run Code Online (Sandbox Code Playgroud)
或者(如果A是一个角色而不是factor)
indx <- with(df, ave(A, ID , FUN = function(x) length(unique(x)))) == 1L
Run Code Online (Sandbox Code Playgroud)
然后简单地运行 split
split(df, indx)
# $`FALSE`
# ID A B C
# 1 1 X 1 10
# 2 1 X 2 10
# 3 1 Z 3 15
# 4 1 Y 4 12
# 5 2 Y 1 15
# 6 2 X 2 13
# 7 2 X 3 13
# 8 2 Y 4 13
#
# $`TRUE`
# ID A B C
# 9 3 Y 1 16
# 10 3 Y 2 18
# 11 3 Y 3 19
# 12 3 Y 4 10
Run Code Online (Sandbox Code Playgroud)
这将返回包含两个数据帧的列表.
与之相似 data.table
library(data.table)
setDT(df)[, indx := !var(A), by = ID]
split(df, df$indx)
Run Code Online (Sandbox Code Playgroud)
要么 dplyr
library(dplyr)
df %>%
group_by(ID) %>%
mutate(indx = !var(A)) %>%
split(., indx)
Run Code Online (Sandbox Code Playgroud)