I've got a dataset like the following.
df <- read.table(header=TRUE, text="
T_A_01_F_1 T_A_02_F_1 T_A_03_F_1 T_A_01_F_2 T_A_02_F_2 T_A_03_F_2 T_A_01_U_1 T_A_02_U_1 T_A_03_U_1 T_A_01_U_2 T_A_02_U_2 T_A_03_U_2 T_B_01_F_1 T_B_02_F_1 T_B_03_F_1 T_B_01_F_2 T_B_02_F_2 T_B_03_F_2 T_B_01_U_1 T_B_02_U_1 T_B_03_U_1 T_B_01_U_2 T_B_02_U_2 T_B_03_U_2
1 2 3 NA NA NA 2 2 2 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
2 2 5 NA NA NA 1 3 3 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
5 3 3 NA NA NA 2 1 2 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
2 4 5 NA NA NA 6 3 4 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
NA NA NA 4 3 5 NA NA NA 4 3 2 NA NA NA NA NA NA NA NA NA NA NA NA
NA NA NA 4 4 5 NA NA NA 2 1 1 NA NA NA NA NA NA NA NA NA NA NA NA
NA NA NA 3 1 4 NA NA NA 2 1 7 NA NA NA NA NA NA NA NA NA NA NA NA
NA NA NA 2 1 6 NA NA NA 3 3 6 NA NA NA NA NA NA NA NA NA NA NA NA
NA NA NA NA NA NA NA NA NA NA NA NA 1 1 1 NA NA NA 2 3 1 NA NA NA
NA NA NA NA NA NA NA NA NA NA NA NA 2 1 1 NA NA NA 3 2 2 NA NA NA
NA NA NA NA NA NA NA NA NA NA NA NA 3 2 1 NA NA NA 4 2 1 NA NA NA
NA NA NA NA NA NA NA NA NA NA NA NA 2 5 4 NA NA NA 6 1 4 NA NA NA
NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 3 2 2 NA NA NA 1 2 5
NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 5 4 4 NA NA NA 3 3 5
NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 5 4 4 NA NA NA 1 3 5
NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 5 1 3 NA NA NA 7 5 1
")
In this case its a 2x2x2 mixed design with "T" being the variable of interest with 3 items, "A" and "B" the between factor, "F" and "U" the within factor and "1" and "2" the between factor. I'd like to reduce the dataset, so that I can compute a cronbachs alpha.
As every Person either got A or B and either 1 or 2 I'd like to combine those items, so that I only have the items T_01_F, T_01_U, T_02_F, T_02_U, T_03_F, T_03_U
I could do this by hand, but does somebody know a quick command with which I could do that?
Thank you so much in advance!!
best, Nash
Perhaps a combination of pivot_longer() and separate() might work since all your column names appear to share the same structure.
library(tidyverse)
df<- df %>%
rownames_to_column() %>%
pivot_longer(cols = T_A_01_F_1:T_B_03_U_2) %>%
separate(col = name, sep = "_", into = c("t", "a_b", "number" , "within", "between"))
I have a data frame like this:
> head(mt)
FID IID PLATE 0VXC556 1CNF297 1CWO500 1DXJ626 1LTX827 1SHK635 1TNP840
1 fam0110 G110 4RWG569 NA NA NA NA NA NA NA
2 fam0113 G113 cherry NA NA NA NA NA NA NA
3 fam0114 G114 cherry NA NA NA NA NA NA NA
4 fam0117 G117 4RWG569 NA NA NA NA NA NA NA
5 fam0118 G118 5XAV049 NA NA NA NA NA NA NA
6 fam0119 G119 cherry NA NA NA NA NA NA NA
1URP242 2BKX529 2PAG415 3DEF425 3ECO791 3FQM386 3KYJ479 3XHK903 4RWG569
1 NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA NA NA
5AMJ101 5AVC089 5GBM583 5XAV049 5ZCV995 6KAE204 6PKP514 6WZD253 7FDZ321
1 NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA NA NA
7MFL836 7PNN733 7RUZ165 8WWR250 9GXO476 9QYW461 9RHL593 9TKZ501 cherry
1 NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA NA NA
...
how do I replace every NA i every column with 2 if the column name matches row value in mt$PLATE and with 1 if that is not true?
for example the first row of mt would only have mt$4RWG569==2 and every other column would be equal 1 in that row.
I tried doing this:
idxs <- t(mapply(cbind, match(colnames(mt), mt$PLATE)))
but then when I tried to this:
> mt[idxs] <- "2"
Error in `[<-.data.frame`(`*tmp*`, idxs, value = "2") :
unsupported matrix index in replacement
it seems that this line solves it:
for(i in 4:ncol(mt)) mt[,i] <- 1 + (names(mt)[i]== mt$PLATE)
I am still quite new to R and I am trying to complete the data wrangling but I am little bit stuck.
I have my data in R organized in the following data frame format (dimensions [24,17]):
Id a b c d e f g h i j k k m n o p
1 999 2 2 999 999 999 999 2 2 2 2 2 2 999 999 999
2 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
7 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
8 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
9 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999
10 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
11 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
12 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
13 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
14 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
15 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
16 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
17 1 3 4 999 2 999 999 999 2 999 999 999 2 2 2 999
18 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
19 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
20 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
21 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
22 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
23 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
24 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
What I try to achieve is to have one column filled with the values for every 8th row (starting from row 1, so row 1,9,17 etc.) where the values other than 999 will be copied below each other in the single column. Where the row only consists of 999 values, I want 8 times 999 below each other in the column. In this particular example with 24 rows the column will be filled (based on row 1, 9, 17) as follows with dimensions [1,24]:
2
2
2
2
2
2
2
2
999
999
999
999
999
999
999
999
1
3
4
2
2
2
2
2
This means that I have to iterate through every column, starting with column 1, row 1 until the end of all columns in row 1 and than move to row 9 column 1 until the end of all columns in row 9 etc.
I looked at examples in R transposing rows to columns with conditions, but I was not able to get the job done.
Given my lack of knowledge here, does someone knows a way to get this done in R?
We can first extract the relevant rows using seq.
df1 <- df[seq(1, nrow(df), 8), ]
Then using apply row-wise we can check if all the values in that row is 999 and return the output accordingly.
c(apply(df1, 1, function(x) if(all(x == 999)) rep(999, 8) else x[x != 999][1:8]))
#[1] 2 2 2 2 2 2 2 2 999 999 999 999 999 999 999 999 1 3 4 2 2 2 2 2
If needed as one column dataframe, we can wrap data.frame around this output.
Say I have a data frame as follows (in reality this is multiple data frames bound):
data.frame(
position = c(3,4,7,12,NA,NA,NA,NA,NA,NA,NA,NA),
colb = c(1,3,8,2,NA,NA,NA,NA,NA,NA,NA,NA),
colc = c(4,6,9,5,NA,NA,NA,NA,NA,NA,NA,NA),
position = c(2,7,8,10,11,12,15,16,19,21,24,26),
colb = c(1,3,8),
colc = c(4,6,9)
)
(Sorry, gets flagged if I post the data format myself.)
How can I transform this so I have a unified system of indicating a 'position'? ie one of the two formats below.
A single column scale:
position colb colc colb.1 colc.1
1 NA NA NA NA
2 NA NA 1 4
3 1 4 NA NA
4 3 6 NA NA
5 NA NA NA NA
6 NA NA NA NA
7 8 9 3 6
8 NA NA 8 9
9 NA NA NA NA
10 NA NA 1 4
11 NA NA 3 6
12 2 5 8 9
13 NA NA NA NA
14 NA NA NA NA
15 NA NA 1 4
16 NA NA 3 6
17 NA NA NA NA
18 NA NA NA NA
19 NA NA 8 9
20 NA NA NA NA
21 NA NA 1 4
22 NA NA NA NA
23 NA NA NA NA
24 NA NA 3 6
25 NA NA NA NA
26 NA NA 8 9
Or with separate columns, but 'matching':
position colb colc position.1 colb.1 colc.1
NA NA NA NA NA NA
NA NA NA 2 3 6
3 1 4 NA NA NA
4 3 6 NA NA NA
NA NA NA NA NA NA
NA NA NA NA NA NA
7 8 9 7 1 4
NA NA NA 8 3 6
NA NA NA NA NA NA
NA NA NA 10 1 4
NA NA NA 11 3 6
12 2 5 12 8 9
NA NA NA NA NA NA
NA NA NA NA NA NA
NA NA NA 15 8 9
NA NA NA 16 1 4
NA NA NA NA NA NA
NA NA NA NA NA NA
NA NA NA 19 1 4
NA NA NA NA NA NA
NA NA NA 21 8 9
NA NA NA NA NA NA
NA NA NA NA NA NA
NA NA NA 24 8 9
NA NA NA NA NA NA
NA NA NA 26 8 9
Any help is appreciated. Thanks.
If df contains the dataframe
df <- data.frame(
position = c(3,4,7,12,NA,NA,NA,NA,NA,NA,NA,NA),
colb = c(1,3,8,2,NA,NA,NA,NA,NA,NA,NA,NA),
colc = c(4,6,9,5,NA,NA,NA,NA,NA,NA,NA,NA),
position = c(2,7,8,10,11,12,15,16,19,21,24,26),
colb = c(1,3,8),
colc = c(4,6,9)
)
df1 <- df[,1:3]
df2 <- df[,4:6]
names(df2) <- c("position", "colb", "colc")
df_out <- rbind(df1, df2)
df_out <- df_out[!is.na(df_out$position),]
df_out <- df_out[order(df_out$position),]
df_out
I have vector of values(generated from raster - Raster package - by function clump in R):
values(rc)
1 NA NA NA 2 NA 2 2 NA NA NA NA NA NA NA 2 NA 2 2 NA 2 2 NA NA NA
NA NA NA NA 2 NA NA NA NA NA 3 NA 4 NA 2 NA 2 NA 5 NA NA 3 NA NA 4
NA NA 2 NA NA NA NA NA NA NA NA 4 NA NA NA NA NA NA 6 NA 7 NA 4 NA NA
NA 8 8 NA 6 6 NA NA NA NA 4 NA NA NA NA NA NA NA NA 4 4 4 NA NA 9
NA NA NA NA 10 NA NA NA NA 4 NA 9 9 NA NA NA NA 10 NA NA NA 4 NA NA NA
9 NA NA NA NA NA NA NA NA NA 11 NA NA NA 12 NA NA NA NA
and I would like to find every value which occurs only once(so 1,5,11,10) and replace it by NA. What I would like to obtain:
values(replaced_rc)
NA NA NA NA 2 NA 2 2 NA NA NA NA NA NA NA 2 NA 2 2 NA 2 2 NA NA NA
NA NA NA NA 2 NA NA NA NA NA 3 NA 4 NA 2 NA 2 NA NA NA NA 3 NA NA 4
NA NA 2 NA NA NA NA NA NA NA NA 4 NA NA NA NA NA NA 6 NA NA NA 4 NA NA
NA 8 8 NA 6 6 NA NA NA NA 4 NA NA NA NA NA NA NA NA 4 4 4 NA NA 9
NA NA NA NA 10 NA NA NA NA 4 NA 9 9 NA NA NA NA 10 NA NA NA 4 NA NA NA
9 NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA
The problem is that I can easily identify raster patches by function clump. And I would like to exclude patches containing only pixel, similarly like function "sieve" in ENVI or ERDAS. Any help? Thanks a lot in advance.
Exemple from R:
library("raster")
r <- raster(ncols=12, nrows=12)
set.seed(0)
r[] <- round(runif(ncell(r))*0.7 )
plot(r)
rc <- clump(r)
replaced_rc<- ???
Using duplicated:
values(rc)[!duplicated(values(rc)) & !duplicated(values(rc),fromLast=T)] <- NA