Reputation: 61
I have a dataset with multiple 0/1 vectors. For every value = 1, I'd like this value to be replaced by a value of another vector with different content. A testdataset would look like this.
name <- c("tim", "tom", "ben", "mary", "jane")
sex <- c("male","male","male","female","female")
jahr <- c(1985, 1986, 1985, 1986, 1984)
v4 <- c(1,0,1,0,1)
v5 <- c(0,0,0,0,1)
v6 <- c(1,0,0,1,1)
v7 <- c(0,0,0,0,0)
df <- data.frame(name, sex, born, v4,v5,v6,v7)
The function I've written looks like this:
df[2,5] <- df[1,"v4"]
yearset <- function(x) {
for (i in 1:ncol(x)) { #jede Spalte
for (j in 1:nrow(x)) { #jede Zeile
if (x[j,i] == 1) { # wenn Wert = 1
x[j,i] <- x[j,"jahr"] # ersetze durch Wert
print(paste("column/variable", i, "and row ", j))
}
}
}
}
Problem: nothing happens. I receive no errors, the IF-loops seem to be correct (as shown by the print command) and the functionality of recode-command has been tested just before. What am I missing?
Upvotes: 0
Views: 104
Reputation: 174506
Are you looking for this?
df[4:7] <- lapply(df[4:7], function(x) ifelse(x == 1, df$born, x))
df
#> name sex born v4 v5 v6 v7
#> 1 tim male 1985 1985 0 1985 0
#> 2 tom male 1986 0 0 0 0
#> 3 ben male 1985 1985 0 0 0
#> 4 mary female 1986 0 0 1986 0
#> 5 jane female 1984 1984 1984 1984 0
EDIT
If you want to be able to select the correct columns programatically, you can find the subset of columns that match your criteria (here, for example you want all columns that are numeric, except the born
column, so you can select only those columns that are numeric and have a maximum value of 1):
num_cols <- sapply(df, function(x) if(!is.numeric(x)) FALSE else max(x) < 2)
df[num_cols] <- lapply(df[num_cols], function(x) ifelse(x == 1, df$born, x))
df
#> name sex born v4 v5 v6 v7
#> 1 tim male 1985 1985 0 1985 0
#> 2 tom male 1986 0 0 0 0
#> 3 ben male 1985 1985 0 0 0
#> 4 mary female 1986 0 0 1986 0
#> 5 jane female 1984 1984 1984 1984 0
Upvotes: 3
Reputation: 887891
We can use sweep
from base R
df[-(1:3)] <- sweep(df[-(1:3)], 1, df$born, `*`)
Upvotes: 0
Reputation: 102710
Try the code below
df[-(1:3)] <- df$born * df[-(1:3)]
or
ids <- startsWith(names(df), "v")
df[ids] <- df$born * df[ids]
giving
> df
name sex born v4 v5 v6 v7
1 tim male 1985 1985 0 1985 0
2 tom male 1986 0 0 0 0
3 ben male 1985 1985 0 0 0
4 mary female 1986 0 0 1986 0
5 jane female 1984 1984 1984 1984 0
Upvotes: 2
Reputation: 146164
Another simplification, this one using multiplication:
cols = paste0("v", 4:7)
df[cols] = df[cols] * df$born
df
# name sex born v4 v5 v6 v7
# 1 tim male 1985 1985 0 1985 0
# 2 tom male 1986 0 0 0 0
# 3 ben male 1985 1985 0 0 0
# 4 mary female 1986 0 0 1986 0
# 5 jane female 1984 1984 1984 1984 0
Upvotes: 2