依次重命名字符变量中的重复值,然后再使用dcast对其重塑

时间:2019-04-01 12:46:02

标签: r reshape reshape2

我正在从一个网站上删除汽车信息,但是我得到的不是固定的,也不是很干净的数据。我正在尝试清理此数据并将其排列到数据框中。

例如:

dd <- data.frame(measure = c("wheel", "wheel", "length", "width", "wheel", "width"), value = 1:6, model = "a", stringsAsFactors = F)
dd
  measure value model
1   wheel     1     a
2   wheel     2     a
3  length     3     a
4   width     4     a
5   wheel     5     a
6   width     6     a

在此示例中,我有3个值wheel和2个值width。在我的真实数据中,重复的东西并不总是相同的,它可以重复也可以不重复,并且可以重复多次。

我需要调整此表的形状以使每个model有一行,但是我不想聚合具有公用value的{​​{1}}。恰好,我希望表格变成:

measure

这是通过 model length wheel wheel1 wheel2 width width1 1 a 3 1 2 5 4 6 手动修改的数据获得的:

dcast

我需要一种修改library(reshape2) res <- data.frame(measure = c("wheel", "wheel1", "length", "width", "wheel2", "width1"), value = 1:6, model = "a", stringsAsFactors = F) dcast(res, model ~ measure) 的方式,以便它不聚合dcast或自动修改measure使其变为dd

我尝试了一些丑陋的尝试,而不是我想要的:

res

此代码不起作用,因为dd[duplicated(dd$measure), "measure"] <- paste0(dd[duplicated(dd$measure), "measure"] , 1:3) dd measure value model 1 wheel 1 a 2 wheel1 2 a 3 length 3 a 4 width 4 a 5 wheel2 5 a 6 width3 6 a 获得的索引为width,而不是3。此外,这将无法适应其他表格,例如:

2

无论如何,我该如何动态修改变量dd2 <- data.frame(measure = c("wheel", "wheel", "length", "width", "wheel"), value = 1:5, model = "a", stringsAsFactors = F) dd2[duplicated(dd2$measure), "measure"] <- paste0(dd2[duplicated(dd2$measure), "measure"] , 1:3) Error in `[<-.data.frame`(`*tmp*`, duplicated(dd2$measure), "measure", : replacement has 3 rows, data has 2 ,使所有单词都是唯一的?

4 个答案:

答案 0 :(得分:1)

您可以按以下方式使用dplyr::mutate

dd <- dd %>%
  group_by(model, measure) %>%
  mutate(measure2 = paste0(measure, ifelse(row_number() > 1, row_number() - 1, ""))) %>%
  ungroup() %>%
  mutate(measure = measure2) %>%
  select(measure, model, value)
dd
# A tibble: 6 x 3
  measure model value
  <chr>   <chr> <int>
1 wheel   a         1
2 wheel1  a         2
3 length  a         3
4 width   a         4
5 wheel2  a         5
6 width1  a         6

答案 1 :(得分:1)

另一种tidyverse可能性是:

dd %>%
 arrange(model, measure) %>%
 group_by(model, measure) %>%
 mutate(var = paste(measure, seq_along(measure), sep = "_")) %>%
 ungroup() %>%
 select(-measure) %>%
 spread(var, value)

  model length_1 wheel_1 wheel_2 wheel_3 width_1 width_2
  <chr>    <int>   <int>   <int>   <int>   <int>   <int>
1 a            3       1       2       5       4       6

答案 2 :(得分:1)

full.table<- read.table("https://pastebin.com/raw/kTQhuttv", header=T, sep="") sample.finished.table <- read.table("https://pastebin.com/raw/Phg7C9xD", header=T, sep="") 就是这样:

make.unique

答案 3 :(得分:0)

您还可以使用sapply

重新编号值
sapply(unique(dd$measure), function(x) {
  z <- dd$measure[dd$measure %in% x]
  if (length(z) > 1)
  dd$measure[dd$measure %in% x] <<- paste0(z, ".", seq(length(z)))
})

,然后使用reshape

reshape(dd, direction="wide", timevar="measure", idvar="model")
#   model value.wheel.1 value.wheel.2 value.length value.width.1 value.wheel.3 value.width.2
# 1     a             1             2            3             4             5             6

数据

dd <- structure(list(measure = c("wheel", "wheel", "length", "width", "wheel", "width"), 
                     value = 1:6, model = c("a", "a", "a", "a", "a", "a")), 
                class = "data.frame", row.names = c(NA, -6L))