-
Notifications
You must be signed in to change notification settings - Fork 0
/
vary_on_model.R
122 lines (98 loc) · 4.84 KB
/
vary_on_model.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# Script vary faces on a model dimension by projecting on preset values (-3 to 3 SDs)
# rather than added/subtracted value from original face values
# Note the difference from vary_on_model_add.R
#
# original code by Ron Dotsch (rdotsch@gmail.com) circa 2017
# modified by DongWon Oh (dongwonohphd@gmail.com) 2024
# System prerequisite: none
library(dplyr)
library(tidyr)
setwd("/path/to/FGBinTools/")
# Read files
models <- read.csv('/path/to/models.csv', header=F)
names(models) <- c('name', paste0('c', 1:100))
identities <- read.csv('/path/to/identities.csv', header=F)
names(identities)[1] <- 'name'
# Select relevant models
models <- models %>% filter(name %in% c('Particular Model 1','Particular Model 2')) # you need this one particular social trait model
#############################
#### Compute projections ####
#############################
# Function to compute projection of v1 on v2
project <- function(v1, v2) {
return(as.numeric((v1 %*% v2) / (v2 %*% v2)))
}
projections <- data.frame()
for (d in 1:nrow(models)) {
model.label <- models[d, 1]
model <- as.vector(as.matrix(models[d, 2:101]) * 1000)
for (i in 1:nrow(identities)) {
identity.label <- identities[i, 1]
identity <- as.vector(as.matrix(identities[i, 2:101]))
projections <- rbind(projections, data.frame(
identity=identity.label,
trait=model.label,
projection.type='shape.and.texture',
projection=project(identity, model)))
projections <- rbind(projections, data.frame(
identity=identity.label,
trait=model.label,
projection.type='shape.only',
projection=project(identity[1:50], model[1:50])))
projections <- rbind(projections, data.frame(
identity=identity.label,
trait=model.label,
projection.type='texture.only',
projection=project(identity[51:100], model[51:100])))
}
}
projections <- projections %>% spread(trait, projection)
#write.csv(projections, 'Projections.csv', row.names=F) # saves what values each of the initial faces has on the social trait model
####################################
#### Select relevant identities ####
####################################
#### Select identities to manipulate ####
identities <- identities %>% filter(name %in% c('face1','face2'))
# For each identity, find the closest point in range, and move to that point (shape & texture)
range.shape = seq(from=-2,to=2,length.out=2)
range.texture = seq(from=2,to=-2,length.out=2)
points <- data.frame()
niter <- nrow(models) * nrow(identities) * length(range.shape)
pb <- progress_estimated(niter)
for (d in 1:nrow(models)) {
model.label <- models[d, 1]
model <- as.vector(as.matrix(models[d, 2:101]) * 1000)
for (i in 1:nrow(identities)) {
identity.label <- identities[i, 1]
identity <- as.vector(as.matrix(identities[i, 2:101]))
#### Create trait variations of identities ####
# Find closest point in range to projection (shape & texture)
projection.shape <- project(identity[1:50], model[1:50])
closest.point.in.range.shape <- which.min(abs(range.shape - projection.shape))
projection.texture <- project(identity[51:100], model[51:100])
closest.point.in.range.texture <- which.min(abs(range.texture - projection.texture))
# Translate identity to that point to create the base.coordinate (shape & texture)
base.coord.shape <- identity[1:50] + ( range.shape[closest.point.in.range.shape] - projection.shape ) * model[1:50]
base.coord.texture <- identity[51:100] + (range.texture[closest.point.in.range.texture] - projection.texture) * model[51:100]
# Create all points
for (point in 1:length(range.shape)) {
pb$tick()$print()
point.coord <- cbind(base.coord.shape + (range.shape[point] - range.shape[closest.point.in.range.shape]) * model[1:50],
base.coord.texture + (range.texture[point] - range.texture[closest.point.in.range.texture]) * model[51:100])
point.coord <- data.frame(matrix(point.coord, nrow = 1))
names(point.coord) <-paste0('c', 1:100)
points <- rbind(points, cbind(data.frame(identity=identity.label,
manipulated.trait=model.label,
identity.point.shape =closest.point.in.range.shape,
identity.point.texture=closest.point.in.range.texture,
point=point,
projection.shape = range.shape[point],
projection.texture= range.texture[point]),
round(point.coord))
)
}
}
}
pb$stop()
# Write the resulting coordinates of identities after variation
write.csv(points, 'identities_outcome.csv', row.names=F)