为R中的3D绘图重新构造数据帧
我经常意识到,3D绘图并不是表示一组数据的最有效方式,但我之前为特定数据集绘制的2D绘图似乎表明,3D绘图有助于将信息分解为更清晰的聚类进行分析。也就是说,我从来没有在R中这样做过,在使用plot3d()制作3D散点图之前,我很难重新构造数据帧 目前,我的数据框有两列和几千行信息。第一列是一个标识符,A,B,C。。。第2列是该标识符的一个度量特征 前 我将在Y轴上绘制该区域。使用类似table()的函数,我可以得到a、B或C出现的次数:(a=3、B=2、C=3),该值将成为所有ID的x坐标。但是我想做的是把这些信息也放进第三列,为给定的x坐标指定一个唯一的z。换句话说,Z应该表示给定X出现的次数,并且对于特定X的每个新实例,Z将增加1。最终,原因是特定ID内所有对象的面积值(y)在唯一的X,Z坐标上相互堆叠。这就是我被困的地方。 基本上,我希望给定上述输入的最终数据帧输出如下所示:为R中的3D绘图重新构造数据帧,r,dataframe,scatter-plot,R,Dataframe,Scatter Plot,我经常意识到,3D绘图并不是表示一组数据的最有效方式,但我之前为特定数据集绘制的2D绘图似乎表明,3D绘图有助于将信息分解为更清晰的聚类进行分析。也就是说,我从来没有在R中这样做过,在使用plot3d()制作3D散点图之前,我很难重新构造数据帧 目前,我的数据框有两列和几千行信息。第一列是一个标识符,A,B,C。。。第2列是该标识符的一个度量特征 前 我将在Y轴上绘制该区域。使用类似table()的函数,我可以得到a、B或C出现的次数:(a=3、B=2、C=3),该值将成为所有ID的x坐标。但是
ID(x) Area(y) Z
3 1.2 1
3 3.0 1
3 2.7 1
2 1.4 1
2 2.5 1
3 4.3 2
3 2.1 2
3 1.7 2
我们可以通过两种方式做到这一点 1。基本R-聚合/平均值 我们可以使用
aggregate
获取“ID”列中每个元素(“IDx”)的长度,通过基于“IDx”中的重复元素创建“Z”列来转换输出数据集(“dfN”),并将“dfN”与原始数据集“df1”进行“合并”
dfN <- aggregate(cbind(IDx=seq_along(ID))~ID, df1, FUN=length)
dfN$Z <- with(dfN, ave(IDx, IDx, FUN=function(x) cumsum(duplicated(x))+1L))
merge(df1, dfN, by='ID')[-1]
# Area IDx Z
#1 1.2 3 1
#2 3.0 3 1
#3 2.7 3 1
#4 1.4 2 1
#5 2.5 2 1
#6 4.3 3 2
#7 2.1 3 2
#8 1.7 3 2
3。数据表
将“data.frame”转换为“data.table”(setDT
),创建“IDx”,即按“ID”分组的nrows(.N
)。基于“IDx”中的重复元素,我们可以创建“Z”列。将键设置为“ID”(setkey
),与“df1”连接,并将不必要的列分配给NULL(ID:=NULL
)
4。dplyr
这个想法与上面的类似。我们使用left\u join
library(dplyr)
left_join(df1,
df1 %>%
group_by(ID) %>%
summarise(IDx=n()) %>%
group_by(IDx) %>%
mutate(Z=cumsum(duplicated(IDx))+1L), by='ID') %>%
select(-ID)
# Area IDx Z
#1 1.2 3 1
#2 3.0 3 1
#3 2.7 3 1
#4 1.4 2 1
#5 2.5 2 1
#6 4.3 3 2
#7 2.1 3 2
#8 1.7 3 2
注意:使用另一个数据集“df2”对此进行了测试
数据
df1列Z不应该是[1,1,1,2,2,3,3]
?否,X表示具有特定ID的对象的数量,Z表示给定X出现的次数。对于第一组3,z=1,因为这是第一组3。当x=2时,Z又是1,因为这是2第一次出现。@akrun,处理好了,谢谢你的帮助tip@MilesW使用merge
时,两个数据集中可能都不存在该列。请检查其中一个数据集中是否有ID
的前置/后置空格。另外@MilesW如果你不能找出问题所在,你可以用一个小数据集的dput输出来更新帖子,这个小数据集会重现错误。也就是说,dput(液滴液位(头部(你的数据,20))
df1$IDx <- with(df1, ave(seq_along(ID), ID, FUN=length))
v1 <- with(df1, paste0(ID, IDx))
df1$Z <- inverse.rle(within.list(rle(v1), values <-ave(lengths,
lengths, FUN=function(x) cumsum(duplicated(x))+1L)))
df1
# ID Area IDx Z
#1 A 1.2 3 1
#2 A 3.0 3 1
#3 A 2.7 3 1
#4 B 1.4 2 1
#5 B 2.5 2 1
#6 C 4.3 3 2
#7 C 2.1 3 2
#8 C 1.7 3 2
library(data.table)
setkey(setDT(df1)[, list(IDx=.N), by = ID][, IDx1:= IDx][,
list(ID,Z=cumsum(duplicated(IDx1))+1L) , IDx], ID)[df1][, ID := NULL][]
# IDx Z Area
#1: 3 1 1.2
#2: 3 1 3.0
#3: 3 1 2.7
#4: 2 1 1.4
#5: 2 1 2.5
#6: 3 2 4.3
#7: 3 2 2.1
#8: 3 2 1.7
library(dplyr)
left_join(df1,
df1 %>%
group_by(ID) %>%
summarise(IDx=n()) %>%
group_by(IDx) %>%
mutate(Z=cumsum(duplicated(IDx))+1L), by='ID') %>%
select(-ID)
# Area IDx Z
#1 1.2 3 1
#2 3.0 3 1
#3 2.7 3 1
#4 1.4 2 1
#5 2.5 2 1
#6 4.3 3 2
#7 2.1 3 2
#8 1.7 3 2
df1 <- structure(list(ID = c("A", "A", "A", "B", "B", "C", "C", "C"),
Area = c(1.2, 3, 2.7, 1.4, 2.5, 4.3, 2.1, 1.7)), .Names = c("ID",
"Area"), class = "data.frame", row.names = c(NA, -8L))
df2 <- structure(list(ID = c("A", "A", "A", "B", "B", "C", "C", "C",
"D", "D", "D", "E", "E", "F"), Area = c(1.2, 3, 2.7, 1.4, 2.5,
4.3, 2.1, 1.7, 1.2, 1.4, 2.1, 1.2, 1.5, 2.3)), .Names = c("ID",
"Area"), class = "data.frame", row.names = c(NA, -14L))