我的数据框看起来像可以使用以下代码复制的数据框:
reproduce.df <- rbind.data.frame(replicate(6,sample(1:50, 50, rep = TRUE)),replicate(6,sample(NA, 5, rep = TRUE)),replicate(6,sample(1:50, 50, rep = TRUE)))
我尝试过: 使用剪切功能在第1列中分配标签并将其添加到数据框中。代码如下:
labels.v1 <- cut(reproduce.df[,1], quantile(reproduce.df[,1], seq(from = 0, to = 1, length.out = 4), na.rm = TRUE), labels = seq(1:3), include.lowest = TRUE)
reproduce.df2 <- cbind.data.frame(reproduce.df,labels.v1)
但是,我无法将此逻辑扩展到下一步。 对于下一步,我使用&#39; by&#39;功能是根据第1列标签将数据框分成3个部分,然后为这3个部分分配标签。
by(reproduce.df2$V2, reproduce.df2$labels.v1, FUN = function(x) cut(x, quantile(x, seq(from=0,to=1,length.out = 4), na.rm = TRUE), labels = c("1","2","3"), include.lowest = TRUE))
虽然这样可行,但它提供的输出是列表格式,不能直接与数据帧合并。此外,它从数据帧中删除NA,我想保留NA,因为这些列是较大数据帧的一部分,我想只是合并标签与该数据帧。
我如何在R?
中执行此过程答案 0 :(得分:1)
如果真的想要使用基础R,可以这样做,但dplyr
甚至data.table
会更容易。
您确定的第一个问题是by
会返回一个列表。您可以简单地unlist()
输出以获得向量。 但这会产生新问题 - 您的原始数据未排序,因此未列出的数据不会按正确的顺序排列。所以,首先我们需要对数据进行排序。
reproduce.df2 <- cbind.data.frame(reproduce.df,labels.v1)[order(labels.v1),]
labels.v2 <- unlist(by(reproduce.df2$V2, reproduce.df2$labels.v1, FUN = function(x) cut(x, quantile(x, seq(from=0,to=1,length.out = 4), na.rm = TRUE), labels = c("1","2","3"), include.lowest = TRUE)))
但是现在你遇到了一个新问题 - 你的数据框架的NA,特别是labels.v1
没有被包含在内,所以labels.v2
现在太短了。您需要过滤掉任何具有NA的行才能使其正常工作。对于接下来的步骤,您需要将标签列粘贴在一起进行排序,以使嵌套排序正常工作。
那么使用dplyr
呢?
library(dplyr)
set.seed(1001)
reproduce.df <- rbind.data.frame(replicate(6,sample(1:50, 50, rep = TRUE)),replicate(6,sample(NA, 5, rep = TRUE)),replicate(6,sample(1:50, 50, rep = TRUE)))
breaks <- seq(0,1,length.out=4)
reproduce.df <- mutate(reproduce.df,labels.v1 = cut(V1,quantile(V1,breaks,na.rm=T),labels=FALSE,include.lowest=TRUE))
reproduce.df <- group_by(reproduce.df,labels.v1)
reproduce.df <- mutate(reproduce.df,labels.v2 = cut(V2,breaks=quantile(V2,breaks,na.rm=T),labels=FALSE,include.lowest=TRUE))
reproduce.df <- group_by(reproduce.df,labels.v1,labels.v2)
reproduce.df <- mutate(reproduce.df,labels.v3 = cut(V3,breaks=quantile(V3,breaks,na.rm=T),labels=FALSE,include.lowest=TRUE))
在每一步中,您都会将之前的标签添加到group_by
和mutate
(创建变量)新标签。
注意 - 我设置了labels = FALSE
因为它没有指定标签1:3
。这样它无论如何都只输出1到3的整数。
您可以在上面的代码末尾看到输出。
> arrange(reproduce.df,labels.v1,labels.v2,labels.v3)
# A tibble: 105 x 9
# Groups: labels.v1, labels.v2 [10]
V1 V2 V3 V4 V5 V6 labels.v1 labels.v2 labels.v3
<int> <int> <int> <int> <int> <int> <int> <int> <int>
1 5 3 3 9 10 34 1 1 1
2 3 2 13 15 7 11 1 1 1
3 14 5 24 16 19 3 1 1 1
4 5 14 20 3 45 34 1 1 1
5 4 17 3 15 16 12 1 1 1
6 1 15 41 15 48 47 1 1 2
7 15 4 31 29 39 25 1 1 2
8 15 8 26 41 42 8 1 1 2
9 4 11 28 45 11 46 1 1 2
10 5 13 46 42 34 18 1 1 3
# ... with 95 more rows
答案 1 :(得分:1)
有...
library(data.table)
setDT(DF)
DF[, v := ""]
for (k in names(DF)[1:6]){
DF[!is.na(get(k)), v := paste0(v, cut(get(k), 3, FALSE)), by=v]
DF[is.na(get(k)), v := paste0(v, "-")]
}
V1 V2 V3 V4 V5 V6 v
1: 42 33 10 8 26 35 321122
2: 21 35 42 46 9 2 233322
3: 10 26 18 25 40 17 121232
4: 22 35 26 34 3 1 232322
5: 26 30 23 2 23 24 222122
---
101: 25 26 18 8 31 24 221123
102: 2 37 13 28 34 33 131232
103: 10 5 14 20 33 29 111122
104: 27 50 18 1 18 33 231112
105: 16 42 23 3 14 35 132122
我尝试使用基础R中的ave
来执行此操作,但处理起来太烦人了。
使用替换值-
,因为如果某些列丢失而其他列不在一行内,则留空或NA无效。