在R中理解应用和外部功能

Jay*_*han 4 r

假设我有一个看起来像这样的数据

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.如果有人能帮我理解在这种情况下如何使用它.

Dav*_*urg 5

所以基本上你不需要一个带条件的循环,所有你需要做的就是在(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)