R-如何通过从列名中提取项的名称来添加新列来创建新表?
我有一个带有列名的R-如何通过从列名中提取项的名称来添加新列来创建新表?,r,dataframe,R,Dataframe,我有一个带有列名的data.frame: Machine1.workingTime, Machine2.workingTime, Machine3.workingTime, Machine1.producedItems, Machine2.producedItems, ... 随着时间的推移,这个框架可以随着更多的机器而扩展。 我需要制作一个R脚本,在这里我必须获得此解决方案: workingTime, producedItems, MachineNum 其中MachineNum是从中获取数
data.frame
:
Machine1.workingTime, Machine2.workingTime, Machine3.workingTime,
Machine1.producedItems, Machine2.producedItems, ...
随着时间的推移,这个框架可以随着更多的机器而扩展。
我需要制作一个R脚本,在这里我必须获得此解决方案:
workingTime, producedItems, MachineNum
其中MachineNum是从中获取数据的列中的数字。(例如,如果我获取Machine2.workingTime列并将其添加到新创建的列“workingTime”,则“MachineNum”将为2
我必须遍历整个data.frame
,并将列合并到新列中,新列的部分名称为旧的原始名称(例如workingTime)
并从旧原始列名的第一部分筛选MachineNum
在过去的几个小时里,我一直在尝试和搜索,但我找不到任何解决方案。我想(希望)这是关于你正在寻找的。我知道我的答案不是最简洁的,我期待着看到其他更清晰的答案
library(data.table) # for melt() and merge(), other package have similar func.
# Dummy data.frame
df <- data.frame(date = Sys.Date() - 800:1,
matrix(sample(0:10000, 2400), ncol = 6))
colnames(df)[-1] <- paste0("m", 1:3, c(rep(".wt", 3), rep(".pi", 3)))
head(df)
date m1.wt m2.wt m3.wt m1.pi m2.pi m3.pi
1 2015-09-24 6271 2491 6525 6680 7708 2949
2 2015-09-25 1173 5794 5616 7402 3274 8997
3 2015-09-26 516 6659 2144 8739 7168 1704
4 2015-09-27 583 2499 4768 9501 2710 6800
5 2015-09-28 2433 8622 6492 7124 4127 233
6 2015-09-29 3409 662 6952 3824 5755 9479
# Now first take working time (filter using regex) to long form
df_wt <- melt(df[, c("date", grep("wt$", colnames(df), value = TRUE))],
id.vars = c("date"),
value.name = "workingTime",
variable.name = "MachineNum")
df_wt$MachineNum <- gsub("m([0-9]).+", "\\1", df_wt$MachineNum)
head(df_wt)
date MachineNum workingTime
1 2015-09-24 1 6271
2 2015-09-25 1 1173
3 2015-09-26 1 516
4 2015-09-27 1 583
5 2015-09-28 1 2433
6 2015-09-29 1 3409
# Same for produced item
df_pi <- melt(df[, c("date", grep("pi$", colnames(df), value = TRUE))],
id.vars = c("date"),
value.name = "producedItems",
variable.name = "MachineNum")
df_pi$MachineNum <- gsub("m([0-9]).+", "\\1", df_pi$MachineNum)
head(df_pi)
date MachineNum producedItems
1 2015-09-24 1 6680
2 2015-09-25 1 7402
3 2015-09-26 1 8739
4 2015-09-27 1 9501
5 2015-09-28 1 7124
6 2015-09-29 1 3824
# Now merge everything
df_long <- merge(df_wt, df_pi)
head(df_long)
date MachineNum workingTime producedItems
1 2015-09-24 1 6271 6680
2 2015-09-24 2 2491 7708
3 2015-09-24 3 6525 2949
4 2015-09-25 1 1173 7402
5 2015-09-25 2 5794 3274
6 2015-09-25 3 5616 8997
library(data.table)#对于melt()和merge(),其他包具有类似的函数。
#虚拟数据帧
df这里是一种使用reformate2
库的方法
machine1.workingTime <- 1:10
machine2.workingTime <- 21:30
machine1.producedItems <- 101:110
machine2.producedItems <- 201:210
date <- c("2017-01-01","2017-01-02","2017-01-03","2017-01-04","2017-01-05","2017-01-06",
"2017-01-07","2017-01-08","2017-01-09","2017-01-10")
theData <- data.frame(date,
machine1.producedItems,
machine1.workingTime,
machine2.producedItems,
machine2.workingTime
)
library(reshape2)
meltedData <- melt(theData,measure.vars=2:5)
meltedData$variable <- as.character(meltedData$variable)
# now, extract machine numbers and variable names
variableNames <- strsplit(as.character(meltedData$variable),"[.]")
# token after the . is variable name
meltedData$columnName <- unlist(lapply(variableNames,function(x) x[2]))
# since all variables start with word 'machine' we can set chars 8+ as ID
meltedData$machineId <- as.numeric(unlist(lapply(variableNames,function(x) y <- substr(x[1],8,nchar(x[1])))))
theResult <- dcast(meltedData,machineId + date ~ columnName,value.var="value")
head(theResult)
更新(2017年12月2日):响应注释,如果没有其他标识符来唯一区分一台机器的多行,可以使用聚合函数对每台机器进行一次观察
theResult <- dcast(meltedData,machineId ~ columnName,
fun.aggregate=mean,value.var="value")
head(theResult)
更新(2017年12月2日):响应评论,使用唯一序列号区分数据行的解决方案如下所示
machine1.workingTime <- 1:10
machine2.workingTime <- 21:30
machine1.producedItems <- 101:110
machine2.producedItems <- 201:210
id <- 1:length(machine1.workingTime)
theData <- data.frame(id,
machine1.producedItems,
machine1.workingTime,
machine2.producedItems,
machine2.workingTime
)
meltedData <- melt(theData,measure.vars=2:5)
head(meltedData)
meltedData$variable <- as.character(meltedData$variable)
# now, extract machine numbers and variable names
variableNames <- strsplit(as.character(meltedData$variable),"[.]")
meltedData$columnName <- unlist(lapply(variableNames,function(x) x[2]))
meltedData$machineId <- as.numeric(unlist(lapply(variableNames,function(x) y <- substr(x[1],8,nchar(x[1])))))
theResult <- dcast(meltedData,machineId + id ~ columnName,value.var="value")
head(theResult)
请提供包含您的数据框(或与您的数据框类似的合成数据)的代码示例显示了你走了多远以及在哪里遇到了麻烦。不清楚这些是列名还是列中的值。什么是MachineNum
我认为你要搜索的关键字是长格式与宽格式数据,以及如何从长格式转换到宽格式。如果你提供示例数据,你可能会得到更好的答案。我有cre我用所需的列创建了一个新的数据框架。所以workingTime、producesItems、MachineNum等等。我现在需要用大表中的数据填充这个框架,在这个大表中我必须通过检查列名进行筛选。因此,我通过筛选列名并将字符串与新列名进行比较来找出保存位置,但我不知道如何进行。Machine2.workingTime必须过滤为“workingTime”2将此列的值插入新的workingTime列,将2插入machineNum列。必须对整个选项卡执行此操作,在该选项卡中,我最多可以获得1000台机器DF_wt$machineNum,如果您没有日期,我想您需要一些id变量来标记跟踪观察结果……我可以以某种方式使用初始行数吗his似乎一直工作到result@Rnooby-除非数据帧中只有一行,否则您需要某种方法来区分输出中的多行与dcast()
。@snoram的解决方案强调了相同的问题:您需要某种ID变量来区分每个机器ID的多行,或者需要使用聚合函数,如sum()
或mean()
。我可以使用初始行数吗?我对R很陌生,这一点我自己很难理解。谢谢大家的帮助。@Rnooby请使用dput()好吗
在您的问题中发布一些数据,以便我们查看输入?然后我们可以帮助您获得正确的结果。此外,如果您觉得答案有用,请向上投票/接受答案。我无法发布数据,但我可以描述融化的数据的外观。列名:变量、值、columnName、machineNumber.variable和columnName几乎是一样的。变量像Machine_01.workingTime等等。coulumnNames就是workingTime等等。这看起来很不错。我必须把它们放在一个表中,看起来像这样:MachineNumber,workingTime,振动率,producedItems,(所有其他列名都是列)但是没有唯一的字段。每一行中都可以有dublicated。因此,第1行的值可以与第2行、第3行的值相同,依此类推。
> head(theResult)
machineId producedItems workingTime
1 1 105.5 5.5
2 2 205.5 25.5
>
machine1.workingTime <- 1:10
machine2.workingTime <- 21:30
machine1.producedItems <- 101:110
machine2.producedItems <- 201:210
id <- 1:length(machine1.workingTime)
theData <- data.frame(id,
machine1.producedItems,
machine1.workingTime,
machine2.producedItems,
machine2.workingTime
)
meltedData <- melt(theData,measure.vars=2:5)
head(meltedData)
meltedData$variable <- as.character(meltedData$variable)
# now, extract machine numbers and variable names
variableNames <- strsplit(as.character(meltedData$variable),"[.]")
meltedData$columnName <- unlist(lapply(variableNames,function(x) x[2]))
meltedData$machineId <- as.numeric(unlist(lapply(variableNames,function(x) y <- substr(x[1],8,nchar(x[1])))))
theResult <- dcast(meltedData,machineId + id ~ columnName,value.var="value")
head(theResult)
head(theResult)
machineId id producedItems workingTime
1 1 1 101 1
2 1 2 102 2
3 1 3 103 3
4 1 4 104 4
5 1 5 105 5
6 1 6 106 6
>