R - 查找和组合多个字符列
R - Finding and combining multiple character columns
总之,我有点想做model.matrix()
的逆过程。我从一项调查中获得了以下数据。
问题 1:从 'Cat'、'Dog' 或 'Sheep'
中选择一个
问题 2:选择一个随机数
问题 3:从 'Big' 或 'Small'
中选择一个
结果按以下方式放入数据框中:
id ans_1 ans_2 ans_3 num size_1 size_2
1 Cat 0 0 0.76 0 Small
2 0 Dog 0 0.44 0 Small
3 0 0 Sheep 0.52 Big 0
4 0 0 Sheep 0.52 Big 0
5 0 Dog 0 0.59 0 Small
6 Cat 0 0 0.97 0 Small
7 0 Dog 0 0.5 0 Small
8 0 Dog 0 0.19 0 Small
9 0 0 Sheep 0.01 Big 0
10 Cat 0 0 0.24 0 Small
我想做的是将每个问题的答案合并到一个列中。在此示例中,ans_1、ans_2 和 ans_3 来自同一个问题,size_1 和 size_2 也来自同一个问题。将它们结合起来,结果如下:
id ans num size
1 Cat 0.76 Small
2 Dog 0.44 Small
3 Sheep 0.52 Big
4 Sheep 0.52 Big
5 Dog 0.59 Small
6 Cat 0.97 Small
7 Dog 0.5 Small
8 Dog 0.19 Small
9 Sheep 0.01 Big
10 Cat 0.24 Small
我有多个数据集,每个数据集包含大约 100 列。这使得手工完成的工作量太大。请注意,还有像 'num' 这样的列,它们是独立存在的。同一个问题的答案总是紧挨着,就像这个例子一样。
谢谢!
数据
id = 1:10
ans_1 = c('Cat', 0, 0, 0, 0, 'Cat', 0, 0, 0, 'Cat')
ans_2 = c(0, 'Dog', 0, 0, 'Dog', 0, 'Dog', 'Dog', 0, 0)
ans_3 = c(0, 0, 'Sheep', 'Sheep', 0, 0, 0, 0, 'Sheep', 0)
num = round(runif(10),2)
size_1 = c(0, 0, 'Big', 'Big', 0, 0, 0, 0, 'Big', 0)
size_2 = c('Small', 'Small', 0, 0, 'Small', 'Small', 'Small', 'Small', 0,
'Small')
data <- noquote(cbind(id, ans_1, ans_2, ans_3, num, size_1, size_2))
您可以使用矩阵子集和 max.col
来完成此操作。
dataNew <- data.frame(id=data$id,
ans=data[,2:4][cbind(seq_along(data$id), max.col(data[, 2:4] != "0"))],
num=data$num,
size=data[,6:7][cbind(seq_along(data$id), max.col(data[, 6:7] != "0"))],
stringsAsFactors=FALSE)
第三个变量 num 是通过对变量 2:4 进行子集化,然后使用矩阵子集化对每行中对应于所需输出的 return 个元素创建的。在这种情况下,seq_along
return 是一组行,max.col
用于查找每行中不为 0 的变量。
数据
data <-
structure(list(id = 1:10, ans_1 = c("Cat", "0", "0", "0", "0",
"Cat", "0", "0", "0", "Cat"), ans_2 = c("0", "Dog", "0", "0",
"Dog", "0", "Dog", "Dog", "0", "0"), ans_3 = c("0", "0", "Sheep",
"Sheep", "0", "0", "0", "0", "Sheep", "0"), num = c(0.44, 0.36,
0.2, 0.72, 0.98, 0.94, 0.52, 0.84, 0.34, 0.04), size_1 = c("0",
"0", "Big", "Big", "0", "0", "0", "0", "Big", "0"), size_2 = c("Small",
"Small", "0", "0", "Small", "Small", "Small", "Small", "0", "Small"
)), .Names = c("id", "ans_1", "ans_2", "ans_3", "num", "size_1",
"size_2"), row.names = c(NA, -10L), class = "data.frame")
您可能想使用来自 tidyr 的 unite()
,然后来自 dplyr 的 mutate_if()
:
library(dplyr)
library(tidyr)
library(stringr)
data <- data_frame(id, ans_1, ans_2, ans_3, num, size_1, size_2)
data %>%
unite(ans, ans_1, ans_2, ans_3) %>%
unite(size, size_1, size_2) %>%
mutate_if(is.character, str_extract, "[a-zA-Z]+")
#> # A tibble: 10 × 4
#> id ans num size
#> <int> <chr> <dbl> <chr>
#> 1 1 Cat 0.92 Small
#> 2 2 Dog 0.79 Small
#> 3 3 Sheep 0.44 Big
#> 4 4 Sheep 0.67 Big
#> 5 5 Dog 0.00 Small
#> 6 6 Cat 0.61 Small
#> 7 7 Dog 0.67 Small
#> 8 8 Dog 0.95 Small
#> 9 9 Sheep 0.18 Big
#> 10 10 Cat 0.76 Small
如上所述,data.frame可能更合适..
ans<-apply(data[,2:4],1,function(x) x[x!="0"])
(data.new<-cbind(id=data[,1],ans,data[,5:7]))
您可以在选定字段(data[, grep('ans', colnames(data))]
或 data[, c('ans1', 'ans2', 'ans3')]
)上应用函数并询问或非 0 值
ans <- apply(data[, grep('ans', colnames(data))], 1, function(x) x[x!=0])
size <- apply(data[, grep('size', colnames(data))], 1, function(x) x[x!=0])
data2 <- data.frame(id, ans, num, size)
> data2
id ans num size
1 1 Cat 0.79 Small
2 2 Dog 0.66 Small
3 3 Sheep 0.77 Big
4 4 Sheep 0.63 Big
5 5 Dog 0.48 Small
6 6 Cat 0.06 Small
7 7 Dog 0.63 Small
8 8 Dog 0.59 Small
9 9 Sheep 0.24 Big
10 10 Cat 0.96 Small
总之,我有点想做model.matrix()
的逆过程。我从一项调查中获得了以下数据。
问题 1:从 'Cat'、'Dog' 或 'Sheep'
中选择一个
问题 2:选择一个随机数
问题 3:从 'Big' 或 'Small'
结果按以下方式放入数据框中:
id ans_1 ans_2 ans_3 num size_1 size_2
1 Cat 0 0 0.76 0 Small
2 0 Dog 0 0.44 0 Small
3 0 0 Sheep 0.52 Big 0
4 0 0 Sheep 0.52 Big 0
5 0 Dog 0 0.59 0 Small
6 Cat 0 0 0.97 0 Small
7 0 Dog 0 0.5 0 Small
8 0 Dog 0 0.19 0 Small
9 0 0 Sheep 0.01 Big 0
10 Cat 0 0 0.24 0 Small
我想做的是将每个问题的答案合并到一个列中。在此示例中,ans_1、ans_2 和 ans_3 来自同一个问题,size_1 和 size_2 也来自同一个问题。将它们结合起来,结果如下:
id ans num size
1 Cat 0.76 Small
2 Dog 0.44 Small
3 Sheep 0.52 Big
4 Sheep 0.52 Big
5 Dog 0.59 Small
6 Cat 0.97 Small
7 Dog 0.5 Small
8 Dog 0.19 Small
9 Sheep 0.01 Big
10 Cat 0.24 Small
我有多个数据集,每个数据集包含大约 100 列。这使得手工完成的工作量太大。请注意,还有像 'num' 这样的列,它们是独立存在的。同一个问题的答案总是紧挨着,就像这个例子一样。
谢谢!
数据
id = 1:10
ans_1 = c('Cat', 0, 0, 0, 0, 'Cat', 0, 0, 0, 'Cat')
ans_2 = c(0, 'Dog', 0, 0, 'Dog', 0, 'Dog', 'Dog', 0, 0)
ans_3 = c(0, 0, 'Sheep', 'Sheep', 0, 0, 0, 0, 'Sheep', 0)
num = round(runif(10),2)
size_1 = c(0, 0, 'Big', 'Big', 0, 0, 0, 0, 'Big', 0)
size_2 = c('Small', 'Small', 0, 0, 'Small', 'Small', 'Small', 'Small', 0,
'Small')
data <- noquote(cbind(id, ans_1, ans_2, ans_3, num, size_1, size_2))
您可以使用矩阵子集和 max.col
来完成此操作。
dataNew <- data.frame(id=data$id,
ans=data[,2:4][cbind(seq_along(data$id), max.col(data[, 2:4] != "0"))],
num=data$num,
size=data[,6:7][cbind(seq_along(data$id), max.col(data[, 6:7] != "0"))],
stringsAsFactors=FALSE)
第三个变量 num 是通过对变量 2:4 进行子集化,然后使用矩阵子集化对每行中对应于所需输出的 return 个元素创建的。在这种情况下,seq_along
return 是一组行,max.col
用于查找每行中不为 0 的变量。
数据
data <-
structure(list(id = 1:10, ans_1 = c("Cat", "0", "0", "0", "0",
"Cat", "0", "0", "0", "Cat"), ans_2 = c("0", "Dog", "0", "0",
"Dog", "0", "Dog", "Dog", "0", "0"), ans_3 = c("0", "0", "Sheep",
"Sheep", "0", "0", "0", "0", "Sheep", "0"), num = c(0.44, 0.36,
0.2, 0.72, 0.98, 0.94, 0.52, 0.84, 0.34, 0.04), size_1 = c("0",
"0", "Big", "Big", "0", "0", "0", "0", "Big", "0"), size_2 = c("Small",
"Small", "0", "0", "Small", "Small", "Small", "Small", "0", "Small"
)), .Names = c("id", "ans_1", "ans_2", "ans_3", "num", "size_1",
"size_2"), row.names = c(NA, -10L), class = "data.frame")
您可能想使用来自 tidyr 的 unite()
,然后来自 dplyr 的 mutate_if()
:
library(dplyr)
library(tidyr)
library(stringr)
data <- data_frame(id, ans_1, ans_2, ans_3, num, size_1, size_2)
data %>%
unite(ans, ans_1, ans_2, ans_3) %>%
unite(size, size_1, size_2) %>%
mutate_if(is.character, str_extract, "[a-zA-Z]+")
#> # A tibble: 10 × 4
#> id ans num size
#> <int> <chr> <dbl> <chr>
#> 1 1 Cat 0.92 Small
#> 2 2 Dog 0.79 Small
#> 3 3 Sheep 0.44 Big
#> 4 4 Sheep 0.67 Big
#> 5 5 Dog 0.00 Small
#> 6 6 Cat 0.61 Small
#> 7 7 Dog 0.67 Small
#> 8 8 Dog 0.95 Small
#> 9 9 Sheep 0.18 Big
#> 10 10 Cat 0.76 Small
如上所述,data.frame可能更合适..
ans<-apply(data[,2:4],1,function(x) x[x!="0"])
(data.new<-cbind(id=data[,1],ans,data[,5:7]))
您可以在选定字段(data[, grep('ans', colnames(data))]
或 data[, c('ans1', 'ans2', 'ans3')]
)上应用函数并询问或非 0 值
ans <- apply(data[, grep('ans', colnames(data))], 1, function(x) x[x!=0])
size <- apply(data[, grep('size', colnames(data))], 1, function(x) x[x!=0])
data2 <- data.frame(id, ans, num, size)
> data2
id ans num size
1 1 Cat 0.79 Small
2 2 Dog 0.66 Small
3 3 Sheep 0.77 Big
4 4 Sheep 0.63 Big
5 5 Dog 0.48 Small
6 6 Cat 0.06 Small
7 7 Dog 0.63 Small
8 8 Dog 0.59 Small
9 9 Sheep 0.24 Big
10 10 Cat 0.96 Small