将列(长)的级别重塑为新列(宽)
Reshape levels of a column (long) into new columns (wide)
我想在一个 DF 中获取列的级别,并将每个级别添加为新 DF 中的新列。这是一个显示源和理想目标 DF 的玩具数据集。
来源 DF
person hour ride
Bill 1 A
Sue 2 B
Bob 1 C
Jill 3 B
Dan 3 A
Tina 3 A
映射的 DF
hour A B C Saturation
1 1 0 1 .66
2 0 1 0 .33
3 1 1 0 .66
这里是测试数据集:
test_data <- cbind.data.frame(person = c('Bill', 'Sue', 'Bob', 'Jill', 'Dan', 'Tina'),
hour = factor(c(1, 2, 1, 3, 3, 3)),
ride = c('A', 'B', 'C', 'B', 'A', 'A'))
test_data$person <- as.character(test_data$person)
看看 Source
中的每次骑行如何变成 Mapped
中的新专栏。我可以通过
获取关卡并使用它们创建映射的 DF
new_data <- cbind.data.frame(hour = levels(test_data$hour))
但是当我尝试遍历级别以添加新列时,一切都失败了。我看到等级了。
unlist(lapply(levels(test_data$ride), function(x) paste(x)))
产量
[1] "A" "B" "C"
那么如何遍历 $ride
中的级别并在映射的 DF 中添加一列?
奖金:我将 运行 通过 test_data
和 ifelse()
中的每一行 1
在对应于该骑行的列中显示它有骑手,否则 0
,但必须有人知道如何更优雅地做到这一点?就目前而言,我需要为从 $ride
中的级别提取的每一列添加一个 ifelse
,我知道这必须比要求的更冗长。
require(reshape2)
mydat <- recast(test_data,hour~ride)
mydat
hour A B C
1 1 1 0 1
2 2 0 1 0
3 3 2 1 0
# 2nd part
for(i in 2:ncol(mydat)){
for(ii in 1:nrow(mydat)){
if(mydat[ii,i] > 0) {mydat[ii,i] <- 1}
}
}
hour A B C
1 1 1 0 1
2 2 0 1 0
3 3 1 1 0
我们可以使用 dcast
来自 data.table
library(data.table)
dcast(setDT(test_data), hour~ride, value.var="person",
function(x) as.integer(length(x) > 0))[,
Saturation := round(rowSums(.SD)/3,2), .SDcols = A:C][]
# hour A B C Saturation
#1: 1 1 0 1 0.67
#2: 2 0 1 0 0.33
#3: 3 2 1 0 1.00
我想在一个 DF 中获取列的级别,并将每个级别添加为新 DF 中的新列。这是一个显示源和理想目标 DF 的玩具数据集。
来源 DF
person hour ride
Bill 1 A
Sue 2 B
Bob 1 C
Jill 3 B
Dan 3 A
Tina 3 A
映射的 DF
hour A B C Saturation
1 1 0 1 .66
2 0 1 0 .33
3 1 1 0 .66
这里是测试数据集:
test_data <- cbind.data.frame(person = c('Bill', 'Sue', 'Bob', 'Jill', 'Dan', 'Tina'),
hour = factor(c(1, 2, 1, 3, 3, 3)),
ride = c('A', 'B', 'C', 'B', 'A', 'A'))
test_data$person <- as.character(test_data$person)
看看 Source
中的每次骑行如何变成 Mapped
中的新专栏。我可以通过
new_data <- cbind.data.frame(hour = levels(test_data$hour))
但是当我尝试遍历级别以添加新列时,一切都失败了。我看到等级了。
unlist(lapply(levels(test_data$ride), function(x) paste(x)))
产量
[1] "A" "B" "C"
那么如何遍历 $ride
中的级别并在映射的 DF 中添加一列?
奖金:我将 运行 通过 test_data
和 ifelse()
中的每一行 1
在对应于该骑行的列中显示它有骑手,否则 0
,但必须有人知道如何更优雅地做到这一点?就目前而言,我需要为从 $ride
中的级别提取的每一列添加一个 ifelse
,我知道这必须比要求的更冗长。
require(reshape2)
mydat <- recast(test_data,hour~ride)
mydat
hour A B C 1 1 1 0 1 2 2 0 1 0 3 3 2 1 0
# 2nd part
for(i in 2:ncol(mydat)){
for(ii in 1:nrow(mydat)){
if(mydat[ii,i] > 0) {mydat[ii,i] <- 1}
}
}
hour A B C 1 1 1 0 1 2 2 0 1 0 3 3 1 1 0
我们可以使用 dcast
来自 data.table
library(data.table)
dcast(setDT(test_data), hour~ride, value.var="person",
function(x) as.integer(length(x) > 0))[,
Saturation := round(rowSums(.SD)/3,2), .SDcols = A:C][]
# hour A B C Saturation
#1: 1 1 0 1 0.67
#2: 2 0 1 0 0.33
#3: 3 2 1 0 1.00