假设我有一个看起来像这样的数据
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
我想将这些值相互比较,因此如果 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
L 看起来像
ID A B C
3 Y 1 16
3 Y 2 18
3 Y 3 19
3 Y 4 10
在嵌套循环和 if then 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]])
}
我在一些帖子中读到 R 中的嵌套循环可以替换为
apply
和 outer
功能。如果有人可以帮助我了解如何在这种情况下使用它。
最佳答案
所以基本上你不需要这里有条件的循环,你需要做的就是检查 !
中是否存在差异(然后使用 A
将其转换为逻辑)在 B
的每个周期内( ID
s) 通过转换 A
到一个数值(我假设它在你的真实数据集中是 factor
,如果它不是一个因素,你可以在 FUN = function(x) length(unique(x))
中使用 ave
代替),然后是 split
因此。使用基础 R 我们可以使用 ave
对于这样的任务,例如
indx <- !with(df, ave(as.numeric(A), ID , FUN = var))
或者(如果
A
是一个字符而不是一个 factor
)indx <- with(df, ave(A, ID , FUN = function(x) length(unique(x)))) == 1L
然后只需运行
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
这将返回一个包含两个数据框的列表。
与
data.table
类似library(data.table)
setDT(df)[, indx := !var(A), by = ID]
split(df, df$indx)
或
dplyr
library(dplyr)
df %>%
group_by(ID) %>%
mutate(indx = !var(A)) %>%
split(., indx)
关于r - 理解 R 中的应用和外部函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32003864/