添加了更准确的可重现示例,并为原始问题描述合并了正确答案(见下文):
数据框
countrydf <- data.frame(ID = c(1,2,3,4),
CTR1 = c("England", "England", "England", "China"),
CTR2 = c("England", "China", "China", "England"),
CTR3 = c("England", "China", "China", "England"),
CTR4 = c("China", "China", "USA", "England"),
CTR5 = c("USA", "USA", "USA", "China"),
CTR6 = c("England", "England", "USA", "USA"))
理想的结果
CTR1 CTR2 CTR3 CTR4 CTR5 CTR6 ID
1 England England China USA 1
2 England China China USA England 2
3 England China China USA USA 3
4 China England England China USA 4
我是R的新手,目前正在使用边缘列表形式的协作数据,该边缘列表具有32列和大约200.000行,如下所示:
1 A A A B C A
2 A B B B C A
3 A B C C C C
4 B A B A B C
A,B,C代表出版物中参与研究人员的机构的国家。 在真实数据集中,“ A”例如为国家名称,例如“英格兰”或“中国”。
我想保留唯一记录(A)和重复记录(AA),但要删除三元组(AA),并且同一行连续出现更多。协作是通过ID分配给发布的,因此顺序应保持不变以便以后进行分析。但是,行内的顺序无关紧要。
所以,最终看起来应该像这样。
1 A A B C
2 A B B C A
3 A B C C
4 B A B A C
到目前为止,我已经根据1中的2,3,tuple package和triplicated
尝试了一些方法。
df <- data.frame(CTR1 = c("A", "A", "A", "B"), CTR2 = c("A", "B", "B", "A"), CTR3 = c("A", "B", "B", "A"), CTR4 = c("B", "B", "C", "A"), CTR5 = c("C", "C", "C", "B"), CTR6 = c("A", "A", "C", "C"), ID = c(1,2,3,4))
# remember the ID
n <-df$ID
# transpose df (data frame)
dt <- as.data.frame(t(df[, -1]))
colnames(dt) <- n
library(tuple)
dt[!(triplicated(dt) | triplicated(dt, fromLast= TRUE)), ]
# Create new transposed variable
df2 <- as.data.frame(t(df))
但是,我使用dt[!(triplicated(dt) | triplicated(dt, fromLast= TRUE)), ]
删除了完整的行,而不仅仅是删除逐行出现多余的特定记录,这导致我进入下面的4x4表...
CTR1 CTR3 CTR4 CTR5 CTR1 CTR2 CTR3 CTR4 CTR5 CTR6
1 A A B C 1 A A B C
2 A B B C rather than 2 A B B C A
3 A B C C 3 A B C C
4 B A A B 4 B A B A C
我还研究了dplyr
以及响应here和here,但到目前为止还没有找到合适的方法。
解决原始问题的解决方案
library(tidyr)
library(dplyr)
countrydf %>%
unite(concat,CTR1:CTR6, sep = "") %>%
mutate(concat = gsub("([a-zA-Z1-9])\\1{2,}", "\\1\\1-", concat)) %>%
separate(concat, paste0("CTR", 1:6), sep = "(?<=.)", remove = TRUE)
Edit1:为澄清起见,调整了说明:在实际数据集中,“ A”例如为国家名称,例如“英格兰”或“中国”。
Edit2:添加更精确的可重现示例。
答案 0 :(得分:2)
我们可以使用unite
函数(separate
和library(tidyr)
library(dplyr)
df1 %>%
unite(concat,CTR1:CTR6, sep = "") %>%
mutate(concat = gsub("([a-zA-Z1-9])\\1{2,}", "\\1\\1-", concat)) %>%
separate(concat, paste0("CTR", 1:6), sep = "(?<=.)", remove = TRUE)
#> ID CTR1 CTR2 CTR3 CTR4 CTR5 CTR6
#> 1 1 A A - B C A
#> 2 2 A B B - C A
#> 3 3 A B B C C -
#> 4 4 B A A - B C
),并借助regex获得所需的输出。
这应该非常接近您的需求。
library(tidyr)
library(dplyr)
ICT_fn <- function(x){
xsplit <- strsplit(x, '')[[1]]
xsplit[data.table::rowid(xsplit) >= 3] <- '-'
paste(xsplit, collapse = '')}
df1 %>%
unite(concat,CTR1:CTR6, sep = "") %>%
rowwise() %>%
mutate(concat = ICT_fn(concat)) %>%
separate(concat, paste0("CTR", 1:6), sep = "(?<=.)", remove = TRUE)
#> # A tibble: 4 x 7
#> ID CTR1 CTR2 CTR3 CTR4 CTR5 CTR6
#> <dbl> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 1 A A - B C -
#> 2 2 A B B - C A
#> 3 3 A B B C C -
#> 4 4 B A A - B C
感谢@IceCreamToucan的功能:
df2 <- data.frame(ID = c(1,2,3,4),
CTR1 = c("England", "England", "England", "France"),
CTR2 = c("England", "France", "France", "England"),
CTR3 = c("England", "France", "France", "England"),
CTR4 = c("France", "France", "Germany", "England"),
CTR5 = c("Germany", "Germany", "Germany", "France"),
CTR6 = c("England", "England", "Germany", "Germany"))
此更新的解决方案经过最少的调整,也适用于国家/地区名称;看下面:
library(tidyr)
library(dplyr)
ICT_fn <- function(x){ #Credits to IceCreamToucan
xsplit <- strsplit(x, ',')[[1]]
xsplit[data.table::rowid(xsplit) >= 3] <- '-'
paste(xsplit, collapse = ',')}
df2 %>%
unite(concat,CTR1:CTR6, sep = ",") %>%
rowwise() %>%
mutate(concat = ICT_fn(concat)) %>%
separate(concat, paste0("CTR", 1:6), sep = ",", remove = TRUE)
#> # A tibble: 4 x 7
#> ID CTR1 CTR2 CTR3 CTR4 CTR5 CTR6
#> <dbl> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 1 England England - France Germany -
#> 2 2 England France France - Germany England
#> 3 3 England France France Germany Germany -
#> 4 4 France England England - France Germany
supportFragmentManager.beginTransaction()
.replace(R.id.content_fragment, it1,
"name")
.commit()